Compare commits
167 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ac7b5c07d7 | ||
|
|
0cd4a199b0 | ||
|
|
35435d4bd3 | ||
|
|
d0bb147639 | ||
|
|
4723b4541e | ||
|
|
9d23ba0a22 | ||
|
|
a08d42555a | ||
|
|
fd7ad8e779 | ||
|
|
a36c5472d2 | ||
|
|
8bfd891c09 | ||
|
|
ef9f7ca3e7 | ||
|
|
acc443b2cf | ||
|
|
f87e7be12c | ||
|
|
c0614654d9 | ||
|
|
0358637725 | ||
|
|
63b5b6d2b3 | ||
|
|
e675262d51 | ||
|
|
c1e771a89a | ||
|
|
bc7a88baea | ||
|
|
018e0350f8 | ||
|
|
d37ee4d41c | ||
|
|
7793c6c389 | ||
|
|
90ec468240 | ||
|
|
994293e972 | ||
|
|
b57bae4b9e | ||
|
|
e23a10f7f9 | ||
|
|
884ec4e8a5 | ||
|
|
e616916de5 | ||
|
|
8d21516623 | ||
|
|
74368c3dba | ||
|
|
18dbceb36f | ||
|
|
65d39a3702 | ||
|
|
24917e7084 | ||
|
|
e84957e3da | ||
|
|
c11a748908 | ||
|
|
90017051f2 | ||
|
|
fc816628c1 | ||
|
|
46ad273df4 | ||
|
|
b689028e87 | ||
|
|
1e831df1f6 | ||
|
|
c12486bab4 | ||
|
|
52e94a0723 | ||
|
|
16b97f9558 | ||
|
|
dbfa5d4d14 | ||
|
|
ba54d074d8 | ||
|
|
0818d396c5 | ||
|
|
770f3ba5fe | ||
|
|
553034fe52 | ||
|
|
7fe8c9150a | ||
|
|
6c419bc083 | ||
|
|
25321df959 | ||
|
|
cf1b0165af | ||
|
|
c3d358a5b8 | ||
|
|
68497d0258 | ||
|
|
71c3d04681 | ||
|
|
4c89550c43 | ||
|
|
7ebfb22d16 | ||
|
|
6eceac0966 | ||
|
|
fc5aee662d | ||
|
|
5fbbb43839 | ||
|
|
df2cfcb5fc | ||
|
|
623a0d920f | ||
|
|
e8c04f8cb6 | ||
|
|
110c1ac097 | ||
|
|
15ef272790 | ||
|
|
b3a706114c | ||
|
|
cc2d7acaf0 | ||
|
|
dfb86ccdd1 | ||
|
|
0417a69c3e | ||
|
|
2dbafbb4ee | ||
|
|
311c074622 | ||
|
|
a10c7793bb | ||
|
|
0b7d65d331 | ||
|
|
8b954b022b | ||
|
|
0013cbf91f | ||
|
|
1956edd503 | ||
|
|
560ccc1221 | ||
|
|
10a71c182b | ||
|
|
ddc0ed7072 | ||
|
|
c00efe56f4 | ||
|
|
28bcdbd7df | ||
|
|
6a8aed2049 | ||
|
|
a8785fb694 | ||
|
|
dd6d7b3d88 | ||
|
|
94f3819dc6 | ||
|
|
be1f5199f4 | ||
|
|
95aea0e33c | ||
|
|
a1b2735dd8 | ||
|
|
f345175bc2 | ||
|
|
bb45f48ab7 | ||
|
|
b2f27fd873 | ||
|
|
ced32f9bd8 | ||
|
|
dfc3ec9cef | ||
|
|
1896694532 | ||
|
|
5f269cd573 | ||
|
|
6988cd9558 | ||
|
|
2390fae5c4 | ||
|
|
56fce2131c | ||
|
|
7e575e9d7f | ||
|
|
cb4a02949e | ||
|
|
f85a206b9e | ||
|
|
bba7cd0a70 | ||
|
|
e1b2026929 | ||
|
|
c319030373 | ||
|
|
47b63ed1a0 | ||
|
|
7aefe97083 | ||
|
|
89198e0ad4 | ||
|
|
caea6aac81 | ||
|
|
f5224ca1f5 | ||
|
|
b7c49b72b3 | ||
|
|
8ce3c7d70f | ||
|
|
87cf715213 | ||
|
|
2c9c72e06c | ||
|
|
882968c68c | ||
|
|
acc2d7d845 | ||
|
|
9a5aede941 | ||
|
|
e6dd471f8f | ||
|
|
0f55bd92f1 | ||
|
|
7d9dad0289 | ||
|
|
44e494f16f | ||
|
|
2415a72e75 | ||
|
|
9c0718b162 | ||
|
|
d2c50ace99 | ||
|
|
1b646d3bc4 | ||
|
|
82d2aa4acf | ||
|
|
c1256c399a | ||
|
|
2c637fea8a | ||
|
|
4fa54b075c | ||
|
|
ab82be82b2 | ||
|
|
02fdcfde01 | ||
|
|
a96f087ac3 | ||
|
|
75e9fd8417 | ||
|
|
f68e267830 | ||
|
|
8b10b93ee1 | ||
|
|
549de028b6 | ||
|
|
f579f1aa47 | ||
|
|
fcc40d0502 | ||
|
|
b309527264 | ||
|
|
5d19bb8d5d | ||
|
|
af97629912 | ||
|
|
8c000033d3 | ||
|
|
fd0d28e465 | ||
|
|
2123f38394 | ||
|
|
58dff9ada3 | ||
|
|
4fdec765bc | ||
|
|
1020d37256 | ||
|
|
076739db07 | ||
|
|
515e93d88a | ||
|
|
57105b299e | ||
|
|
77e1bda426 | ||
|
|
a59593cac8 | ||
|
|
046bbde9d4 | ||
|
|
fea9da9866 | ||
|
|
4733159782 | ||
|
|
5fba98608c | ||
|
|
c587d7917d | ||
|
|
336336f53f | ||
|
|
4bde50ce85 | ||
|
|
fbecedf94c | ||
|
|
2f31f95095 | ||
|
|
6b603e1a62 | ||
|
|
499f8d89ff | ||
|
|
9eb65f3af3 | ||
|
|
2cbbf5c375 | ||
|
|
3c384cf9a8 | ||
|
|
37f4f56752 | ||
|
|
1e4985ed9e |
25
.github/ISSUE_TEMPLATE.md
vendored
25
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,25 +0,0 @@
|
|||||||
**Bug report or feature request?**
|
|
||||||
|
|
||||||
<!-- Note: sub-optimal but correct code is not a bug -->
|
|
||||||
|
|
||||||
**Uglify version (`uglifyjs -V`)**
|
|
||||||
|
|
||||||
**JavaScript input**
|
|
||||||
|
|
||||||
<!--
|
|
||||||
A complete parsable JS program exhibiting the issue with
|
|
||||||
UglifyJS alone - without third party tools or libraries.
|
|
||||||
Ideally the input should be as small as possible.
|
|
||||||
Post a link to a gist if necessary.
|
|
||||||
|
|
||||||
Issues without a reproducible test case will be closed.
|
|
||||||
-->
|
|
||||||
|
|
||||||
**The `uglifyjs` CLI command executed or `minify()` options used.**
|
|
||||||
|
|
||||||
**JavaScript output or error produced.**
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Note: `uglify-js` only supports JavaScript.
|
|
||||||
Those wishing to minify ES6+ should transpile first.
|
|
||||||
-->
|
|
||||||
51
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
51
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- Note: sub-optimal but correct code is not a bug -->
|
||||||
|
|
||||||
|
**Uglify version (`uglifyjs -V`)**
|
||||||
|
|
||||||
|
**JavaScript input**
|
||||||
|
|
||||||
|
<!--
|
||||||
|
A complete parsable JS program exhibiting the issue with UglifyJS alone
|
||||||
|
- without third party tools or libraries.
|
||||||
|
|
||||||
|
Ideally the input should be as small as possible, but may be large if isolating
|
||||||
|
the problem proves to be difficult. The most important thing is that the
|
||||||
|
standalone program reliably exhibits the bug when minified. Provide a link to a
|
||||||
|
gist if necessary.
|
||||||
|
|
||||||
|
Solely providing minified output without the original uglify JS input is not
|
||||||
|
useful in determining the cause of the problem. Issues without a reproducible
|
||||||
|
test case will be closed.
|
||||||
|
-->
|
||||||
|
|
||||||
|
**The `uglifyjs` CLI command executed or `minify()` options used.**
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Command-line or API call to UglifyJS without third party tools or libraries.
|
||||||
|
|
||||||
|
For users using bundlers or transpilers, you may be able to gather the required
|
||||||
|
information through setting the `UGLIFY_BUG_REPORT` environment variable:
|
||||||
|
|
||||||
|
export UGLIFY_BUG_REPORT=1 (bash)
|
||||||
|
set UGLIFY_BUG_REPORT=1 (Command Prompt)
|
||||||
|
$Env:UGLIFY_BUG_REPORT=1 (PowerShell)
|
||||||
|
|
||||||
|
before running your usual build process. The resulting "minified" output should
|
||||||
|
contain the necessary details for this report.
|
||||||
|
-->
|
||||||
|
|
||||||
|
**JavaScript output or error produced.**
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Only minified code that produces different output (or error) from the original
|
||||||
|
upon execution would be considered a bug.
|
||||||
|
-->
|
||||||
8
.github/workflows/ci.yml
vendored
8
.github/workflows/ci.yml
vendored
@@ -7,13 +7,13 @@ 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', 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:
|
||||||
- node: "0.8"
|
- node: '0.8'
|
||||||
script: release/benchmark
|
script: release/benchmark
|
||||||
- node: "0.8"
|
- node: '0.8'
|
||||||
script: release/jetstream
|
script: release/jetstream
|
||||||
name: ${{ matrix.node }} ${{ matrix.os }} ${{ matrix.script }}
|
name: ${{ matrix.node }} ${{ matrix.os }} ${{ matrix.script }}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
@@ -29,7 +29,7 @@ jobs:
|
|||||||
- name: Perform tests
|
- name: Perform tests
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
git clone --branch v1.5.4 --depth 1 https://github.com/jasongin/nvs.git ~/.nvs
|
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
|
while ! timeout 60 bash -c '. ~/.nvs/nvs.sh add $NODE && nvs use $NODE'; do
|
||||||
cd ~/.nvs
|
cd ~/.nvs
|
||||||
while !(git clean -xdf); do echo "'git clean' failed - retrying..."; done
|
while !(git clean -xdf); do echo "'git clean' failed - retrying..."; done
|
||||||
|
|||||||
31
.github/workflows/ufuzz.yml
vendored
31
.github/workflows/ufuzz.yml
vendored
@@ -2,7 +2,7 @@ name: Fuzzing
|
|||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "*/5 * * * *"
|
- cron: '*/5 * * * *'
|
||||||
env:
|
env:
|
||||||
BASE_URL: https://api.github.com/repos/${{ github.repository }}
|
BASE_URL: https://api.github.com/repos/${{ github.repository }}
|
||||||
CAUSE: ${{ github.event_name }}
|
CAUSE: ${{ github.event_name }}
|
||||||
@@ -13,22 +13,41 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ ubuntu-latest, windows-latest ]
|
include:
|
||||||
name: ${{ matrix.os }}
|
- node: latest
|
||||||
|
os: macos-latest
|
||||||
|
- node: '8'
|
||||||
|
os: ubuntu-latest
|
||||||
|
- node: '8'
|
||||||
|
os: ubuntu-latest
|
||||||
|
- node: '8'
|
||||||
|
os: windows-latest
|
||||||
|
- node: '8'
|
||||||
|
os: windows-latest
|
||||||
|
name: ${{ matrix.node }} ${{ matrix.os }}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
|
env:
|
||||||
|
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.5.4 --depth 1 https://github.com/jasongin/nvs.git ~/.nvs
|
git clone --branch v1.6.0 --depth 1 https://github.com/jasongin/nvs.git ~/.nvs
|
||||||
while ! timeout 60 bash -c '. ~/.nvs/nvs.sh add 8 && nvs use 8'; do
|
while ! timeout 60 bash -c '. ~/.nvs/nvs.sh add $NODE && nvs use $NODE'; do
|
||||||
cd ~/.nvs
|
cd ~/.nvs
|
||||||
while !(git clean -xdf); do echo "'git clean' failed - retrying..."; done
|
while !(git clean -xdf); do echo "'git clean' failed - retrying..."; done
|
||||||
cd -
|
cd -
|
||||||
done
|
done
|
||||||
. ~/.nvs/nvs.sh --version
|
. ~/.nvs/nvs.sh --version
|
||||||
nvs use 8
|
nvs use $NODE
|
||||||
node --version
|
node --version
|
||||||
npm config set audit false
|
npm config set audit false
|
||||||
npm config set optional false
|
npm config set optional false
|
||||||
|
|||||||
115
README.md
115
README.md
@@ -4,10 +4,12 @@ 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) that is not backwards compatible with [`uglify-js@2`](https://github.com/mishoo/UglifyJS/tree/v2.x)**.
|
- **`uglify-js@3` has a simplified [API](#api-reference) and [CLI](#command-line-usage)
|
||||||
|
that is not backwards compatible with [`uglify-js@2`](https://github.com/mishoo/UglifyJS/tree/v2.x)**.
|
||||||
- **Documentation for UglifyJS `2.x` releases can be found [here](https://github.com/mishoo/UglifyJS/tree/v2.x)**.
|
- **Documentation for UglifyJS `2.x` releases can be found [here](https://github.com/mishoo/UglifyJS/tree/v2.x)**.
|
||||||
- `uglify-js` only supports JavaScript (ECMAScript 5).
|
- `uglify-js` supports ECMAScript 5 and some newer language features.
|
||||||
- To minify ECMAScript 2015 or above, transpile using tools like [Babel](https://babeljs.io/).
|
- To minify ECMAScript 2015 or above, you may need to transpile using tools like
|
||||||
|
[Babel](https://babeljs.io/).
|
||||||
|
|
||||||
Install
|
Install
|
||||||
-------
|
-------
|
||||||
@@ -133,6 +135,10 @@ a double dash to prevent input files being used as option arguments:
|
|||||||
`//# sourceMappingURL`.
|
`//# sourceMappingURL`.
|
||||||
--timings Display operations run time on STDERR.
|
--timings Display operations run time on STDERR.
|
||||||
--toplevel Compress and/or mangle variables in top level scope.
|
--toplevel Compress and/or mangle variables in top level scope.
|
||||||
|
--v8 Support non-standard Chrome & Node.js
|
||||||
|
Equivalent to setting `v8: true` in `minify()`
|
||||||
|
for `mangle` and `output` options.
|
||||||
|
By default UglifyJS will not try to be v8-proof.
|
||||||
--verbose Print diagnostic messages.
|
--verbose Print diagnostic messages.
|
||||||
--warn Print warning messages.
|
--warn Print warning messages.
|
||||||
--webkit Support non-standard Safari/Webkit.
|
--webkit Support non-standard Safari/Webkit.
|
||||||
@@ -520,6 +526,8 @@ if (result.error) throw result.error;
|
|||||||
- `toplevel` (default `false`) -- set to `true` if you wish to enable top level
|
- `toplevel` (default `false`) -- set to `true` if you wish to enable top level
|
||||||
variable and function name mangling and to drop unused variables and functions.
|
variable and function name mangling and to drop unused variables and functions.
|
||||||
|
|
||||||
|
- `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.
|
||||||
|
|
||||||
@@ -619,7 +627,11 @@ to be `false` and all symbol names will be omitted.
|
|||||||
- `arguments` (default: `true`) -- replace `arguments[index]` with function
|
- `arguments` (default: `true`) -- replace `arguments[index]` with function
|
||||||
parameter name whenever possible.
|
parameter name whenever possible.
|
||||||
|
|
||||||
- `assignments` (default: `true`) -- apply optimizations to assignment expressions.
|
- `arrows` (default: `true`) -- apply optimizations to arrow functions
|
||||||
|
|
||||||
|
- `assignments` (default: `true`) -- apply optimizations to assignment 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`
|
||||||
@@ -636,6 +648,8 @@ to be `false` and all symbol names will be omitted.
|
|||||||
|
|
||||||
- `dead_code` (default: `true`) -- remove unreachable code
|
- `dead_code` (default: `true`) -- remove unreachable code
|
||||||
|
|
||||||
|
- `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
|
||||||
@@ -681,13 +695,9 @@ to be `false` and all symbol names will be omitted.
|
|||||||
|
|
||||||
- `join_vars` (default: `true`) -- join consecutive `var` statements
|
- `join_vars` (default: `true`) -- join consecutive `var` statements
|
||||||
|
|
||||||
- `keep_fargs` (default: `strict`) -- Discard unused function arguments. Code
|
- `keep_fargs` (default: `false`) -- discard unused function arguments except
|
||||||
which relies on `Function.length` will break if this is done indiscriminately,
|
when unsafe to do so, e.g. code which relies on `Function.prototype.length`.
|
||||||
i.e. when passing `true`. Pass `false` to always retain function arguments.
|
Pass `true` to always retain function arguments.
|
||||||
|
|
||||||
- `keep_fnames` (default: `false`) -- Pass `true` to prevent the
|
|
||||||
compressor from discarding function names. Useful for code relying on
|
|
||||||
`Function.prototype.name`. See also: the `keep_fnames` [mangle option](#mangle-options).
|
|
||||||
|
|
||||||
- `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.
|
||||||
@@ -737,6 +747,8 @@ to be `false` and all symbol names will be omitted.
|
|||||||
- `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
|
||||||
|
|
||||||
- `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
|
||||||
@@ -751,18 +763,20 @@ to be `false` and all symbol names will be omitted.
|
|||||||
annotation `/*@__PURE__*/` or `/*#__PURE__*/` immediately precedes the call. For
|
annotation `/*@__PURE__*/` or `/*#__PURE__*/` immediately precedes the call. For
|
||||||
example: `/*@__PURE__*/foo();`
|
example: `/*@__PURE__*/foo();`
|
||||||
|
|
||||||
|
- `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
|
||||||
|
|
||||||
- `toplevel` (default: `false`) -- drop unreferenced functions (`"funcs"`) and/or
|
|
||||||
variables (`"vars"`) in the top level scope (`false` by default, `true` to drop
|
|
||||||
both unreferenced functions and variables)
|
|
||||||
|
|
||||||
- `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
|
||||||
|
variables (`"vars"`) in the top level scope (`false` by default, `true` to drop
|
||||||
|
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.
|
||||||
@@ -799,10 +813,6 @@ to be `false` and all symbol names will be omitted.
|
|||||||
- `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.
|
||||||
|
|
||||||
- `keep_fnames` (default `false`) -- Pass `true` to not mangle function names.
|
|
||||||
Useful for code relying on `Function.prototype.name`. See also: the `keep_fnames`
|
|
||||||
[compress option](#compress-options).
|
|
||||||
|
|
||||||
- `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"]`.
|
||||||
|
|
||||||
@@ -869,7 +879,7 @@ can pass additional arguments that control the code output:
|
|||||||
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.
|
||||||
```js
|
```javascript
|
||||||
function(node, comment) {
|
function(node, comment) {
|
||||||
return comment.value.indexOf("@type " + node.TYPE) >= 0;
|
return comment.value.indexOf("@type " + node.TYPE) >= 0;
|
||||||
}
|
}
|
||||||
@@ -915,8 +925,6 @@ can pass additional arguments that control the code output:
|
|||||||
|
|
||||||
- `shebang` (default `true`) -- preserve shebang `#!` in preamble (bash scripts)
|
- `shebang` (default `true`) -- preserve shebang `#!` in preamble (bash scripts)
|
||||||
|
|
||||||
- `v8` (default `false`) -- enable workarounds for Chrome & Node.js bugs
|
|
||||||
|
|
||||||
- `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).
|
||||||
@@ -1142,7 +1150,7 @@ To enable fast minify mode from the CLI use:
|
|||||||
uglifyjs file.js -m
|
uglifyjs file.js -m
|
||||||
```
|
```
|
||||||
To enable fast minify mode with the API use:
|
To enable fast minify mode with the API use:
|
||||||
```js
|
```javascript
|
||||||
UglifyJS.minify(code, { compress: false, mangle: true });
|
UglifyJS.minify(code, { compress: false, mangle: true });
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -1173,9 +1181,21 @@ To allow for better optimizations, the compiler makes various assumptions:
|
|||||||
- Object properties can be added, removed and modified (not prevented with
|
- Object properties can be added, removed and modified (not prevented with
|
||||||
`Object.defineProperty()`, `Object.defineProperties()`, `Object.freeze()`,
|
`Object.defineProperty()`, `Object.defineProperties()`, `Object.freeze()`,
|
||||||
`Object.preventExtensions()` or `Object.seal()`).
|
`Object.preventExtensions()` or `Object.seal()`).
|
||||||
|
- Earlier versions of JavaScript will throw `SyntaxError` with the following:
|
||||||
|
```javascript
|
||||||
|
({
|
||||||
|
p: 42,
|
||||||
|
get p() {},
|
||||||
|
});
|
||||||
|
// SyntaxError: Object literal may not have data and accessor property with
|
||||||
|
// the same name
|
||||||
|
```
|
||||||
|
UglifyJS may modify the input which in turn may suppress those errors.
|
||||||
|
- Iteration order of keys over an object which contains spread syntax in later
|
||||||
|
versions of Chrome and Node.js may be altered.
|
||||||
- When `toplevel` is enabled, UglifyJS effectively assumes input code is wrapped
|
- When `toplevel` is enabled, UglifyJS effectively assumes input code is wrapped
|
||||||
within `function(){ ... }`, thus forbids aliasing of declared global variables:
|
within `function(){ ... }`, thus forbids aliasing of declared global variables:
|
||||||
```js
|
```javascript
|
||||||
A = "FAIL";
|
A = "FAIL";
|
||||||
var B = "FAIL";
|
var B = "FAIL";
|
||||||
// can be `global`, `self`, `window` etc.
|
// can be `global`, `self`, `window` etc.
|
||||||
@@ -1193,3 +1213,50 @@ To allow for better optimizations, the compiler makes various assumptions:
|
|||||||
`function({}, arguments) {}` will result in `SyntaxError` in earlier versions
|
`function({}, arguments) {}` will result in `SyntaxError` in earlier versions
|
||||||
of Chrome and Node.js - UglifyJS may modify the input which in turn may
|
of Chrome and Node.js - UglifyJS may modify the input which in turn may
|
||||||
suppress those errors.
|
suppress those errors.
|
||||||
|
- Earlier versions of Chrome and Node.js will throw `ReferenceError` with the
|
||||||
|
following:
|
||||||
|
```javascript
|
||||||
|
var a;
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch ({
|
||||||
|
[a]: b,
|
||||||
|
// ReferenceError: a is not defined
|
||||||
|
}) {
|
||||||
|
let a;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
UglifyJS may modify the input which in turn may suppress those errors.
|
||||||
|
- Later versions of JavaScript will throw `SyntaxError` with the following:
|
||||||
|
```javascript
|
||||||
|
a => {
|
||||||
|
let a;
|
||||||
|
};
|
||||||
|
// SyntaxError: Identifier 'a' has already been declared
|
||||||
|
```
|
||||||
|
UglifyJS may modify the input which in turn may suppress those errors.
|
||||||
|
- Later versions of JavaScript will throw `SyntaxError` with the following:
|
||||||
|
```javascript
|
||||||
|
try {
|
||||||
|
// ...
|
||||||
|
} catch ({ message: a }) {
|
||||||
|
var a;
|
||||||
|
}
|
||||||
|
// SyntaxError: Identifier 'a' has already been declared
|
||||||
|
```
|
||||||
|
UglifyJS may modify the input which in turn may suppress those errors.
|
||||||
|
- Some versions of Chrome and Node.js will throw `ReferenceError` with the
|
||||||
|
following:
|
||||||
|
```javascript
|
||||||
|
console.log(((a, b = function() {
|
||||||
|
return a;
|
||||||
|
// ReferenceError: a is not defined
|
||||||
|
}()) => b)());
|
||||||
|
```
|
||||||
|
UglifyJS may modify the input which in turn may suppress those errors.
|
||||||
|
- Some arithmetic operations with `BigInt` may throw `TypeError`:
|
||||||
|
```javascript
|
||||||
|
1n + 1;
|
||||||
|
// TypeError: can't convert BigInt to number
|
||||||
|
```
|
||||||
|
UglifyJS may modify the input which in turn may suppress those errors.
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
require("../tools/exit");
|
require("../tools/tty");
|
||||||
|
|
||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
var info = require("../package.json");
|
var info = require("../package.json");
|
||||||
@@ -265,7 +265,7 @@ if (paths.length) {
|
|||||||
process.stdin.on("data", function(chunk) {
|
process.stdin.on("data", function(chunk) {
|
||||||
chunks.push(chunk);
|
chunks.push(chunk);
|
||||||
}).on("end", function() {
|
}).on("end", function() {
|
||||||
files = [ chunks.join("") ];
|
files = { STDIN: chunks.join("") };
|
||||||
run();
|
run();
|
||||||
});
|
});
|
||||||
process.stdin.resume();
|
process.stdin.resume();
|
||||||
|
|||||||
318
lib/ast.js
318
lib/ast.js
@@ -160,6 +160,8 @@ var restore_transforms = [];
|
|||||||
AST_Node.enable_validation = function() {
|
AST_Node.enable_validation = function() {
|
||||||
AST_Node.disable_validation();
|
AST_Node.disable_validation();
|
||||||
(function validate_transform(ctor) {
|
(function validate_transform(ctor) {
|
||||||
|
ctor.SUBCLASSES.forEach(validate_transform);
|
||||||
|
if (!HOP(ctor.prototype, "transform")) return;
|
||||||
var transform = ctor.prototype.transform;
|
var transform = ctor.prototype.transform;
|
||||||
ctor.prototype.transform = function(tw, in_list) {
|
ctor.prototype.transform = function(tw, in_list) {
|
||||||
var node = transform.call(this, tw, in_list);
|
var node = transform.call(this, tw, in_list);
|
||||||
@@ -173,7 +175,6 @@ AST_Node.enable_validation = function() {
|
|||||||
restore_transforms.push(function() {
|
restore_transforms.push(function() {
|
||||||
ctor.prototype.transform = transform;
|
ctor.prototype.transform = transform;
|
||||||
});
|
});
|
||||||
ctor.SUBCLASSES.forEach(validate_transform);
|
|
||||||
})(this);
|
})(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -207,11 +208,23 @@ 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 must_be_expression(node, prop) {
|
function validate_expression(value, prop, multiple, allow_spread, allow_hole) {
|
||||||
if (!(node[prop] instanceof AST_Node)) throw new Error(prop + " must be AST_Node");
|
multiple = multiple ? "contain" : "be";
|
||||||
if (node[prop] instanceof AST_Statement && !(node[prop] instanceof AST_Function)) {
|
if (!(value instanceof AST_Node)) throw new Error(prop + " must " + multiple + " AST_Node");
|
||||||
throw new Error(prop + " cannot be AST_Statement");
|
if (value instanceof AST_DefaultValue) throw new Error(prop + " cannot " + multiple + " AST_DefaultValue");
|
||||||
|
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_Spread && !allow_spread) throw new Error(prop + " cannot " + multiple + " AST_Spread");
|
||||||
|
if (value instanceof AST_Statement && !is_function(value)) {
|
||||||
|
throw new Error(prop + " cannot " + multiple + " AST_Statement");
|
||||||
}
|
}
|
||||||
|
if (value instanceof AST_SymbolDeclaration) {
|
||||||
|
throw new Error(prop + " cannot " + multiple + " AST_SymbolDeclaration");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function must_be_expression(node, prop) {
|
||||||
|
validate_expression(node[prop], prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
var AST_SimpleStatement = DEFNODE("SimpleStatement", "body", {
|
var AST_SimpleStatement = DEFNODE("SimpleStatement", "body", {
|
||||||
@@ -236,7 +249,7 @@ var AST_BlockScope = DEFNODE("BlockScope", "enclosed functions make_def parent_s
|
|||||||
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: "[Object/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: "[Object/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);
|
||||||
@@ -278,7 +291,7 @@ var AST_Block = DEFNODE("Block", "body", {
|
|||||||
_validate: function() {
|
_validate: function() {
|
||||||
this.body.forEach(function(node) {
|
this.body.forEach(function(node) {
|
||||||
if (!(node instanceof AST_Statement)) throw new Error("body must be AST_Statement[]");
|
if (!(node instanceof AST_Statement)) throw new Error("body must be AST_Statement[]");
|
||||||
if (node instanceof AST_Function) throw new Error("body cannot contain AST_Function");
|
if (is_function(node)) throw new Error("body cannot contain AST_Function");
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
}, AST_BlockScope);
|
}, AST_BlockScope);
|
||||||
@@ -294,7 +307,7 @@ var AST_StatementWithBody = DEFNODE("StatementWithBody", "body", {
|
|||||||
},
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
if (!(this.body instanceof AST_Statement)) throw new Error("body must be AST_Statement");
|
if (!(this.body instanceof AST_Statement)) throw new Error("body must be AST_Statement");
|
||||||
if (this.body instanceof AST_Function) throw new Error("body cannot be AST_Function");
|
if (is_function(this.body)) throw new Error("body cannot be AST_Function");
|
||||||
},
|
},
|
||||||
}, AST_BlockScope);
|
}, AST_BlockScope);
|
||||||
|
|
||||||
@@ -388,7 +401,7 @@ var AST_For = DEFNODE("For", "init condition step", {
|
|||||||
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 (this.init instanceof AST_Statement
|
||||||
&& !(this.init instanceof AST_Definitions || this.init instanceof AST_Function)) {
|
&& !(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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -459,7 +472,7 @@ var AST_Scope = DEFNODE("Scope", "uses_eval uses_with", {
|
|||||||
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: "[Object/S] a map of name ---> SymbolDef for all undeclared names",
|
||||||
},
|
},
|
||||||
wrap: function(name) {
|
wrap: function(name) {
|
||||||
var body = this.body;
|
var body = this.body;
|
||||||
@@ -500,15 +513,19 @@ var AST_Toplevel = DEFNODE("Toplevel", "globals", {
|
|||||||
}
|
}
|
||||||
}, AST_Scope);
|
}, AST_Scope);
|
||||||
|
|
||||||
var AST_Lambda = DEFNODE("Lambda", "name argnames length_read uses_arguments", {
|
var AST_Lambda = DEFNODE("Lambda", "argnames length_read rest uses_arguments", {
|
||||||
$documentation: "Base class for functions",
|
$documentation: "Base class for functions",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
name: "[AST_SymbolDeclaration?] the name of this function",
|
argnames: "[(AST_DefaultValue|AST_Destructured|AST_SymbolFunarg)*] array of function arguments and/or destructured literals",
|
||||||
argnames: "[(AST_Destructured|AST_SymbolFunarg)*] array of function arguments and/or destructured literals",
|
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] tells 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) {
|
||||||
|
if (node instanceof AST_DefaultValue) {
|
||||||
|
node.name.walk(tw);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (node instanceof AST_DestructuredKeyVal) {
|
if (node instanceof AST_DestructuredKeyVal) {
|
||||||
node.value.walk(tw);
|
node.value.walk(tw);
|
||||||
return true;
|
return true;
|
||||||
@@ -518,6 +535,7 @@ var AST_Lambda = DEFNODE("Lambda", "name argnames length_read uses_arguments", {
|
|||||||
this.argnames.forEach(function(argname) {
|
this.argnames.forEach(function(argname) {
|
||||||
argname.walk(tw);
|
argname.walk(tw);
|
||||||
});
|
});
|
||||||
|
if (this.rest) this.rest.walk(tw);
|
||||||
},
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
@@ -526,6 +544,7 @@ var AST_Lambda = DEFNODE("Lambda", "name argnames length_read uses_arguments", {
|
|||||||
node.argnames.forEach(function(argname) {
|
node.argnames.forEach(function(argname) {
|
||||||
argname.walk(visitor);
|
argname.walk(visitor);
|
||||||
});
|
});
|
||||||
|
if (node.rest) node.rest.walk(visitor);
|
||||||
walk_body(node, visitor);
|
walk_body(node, visitor);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@@ -533,20 +552,104 @@ var AST_Lambda = DEFNODE("Lambda", "name argnames length_read uses_arguments", {
|
|||||||
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[]");
|
||||||
});
|
}, true);
|
||||||
|
});
|
||||||
|
if (this.rest != null) validate_destructured(this.rest, function(node) {
|
||||||
|
if (!(node instanceof AST_SymbolFunarg)) throw new Error("rest must be AST_SymbolFunarg");
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
}, AST_Scope);
|
}, AST_Scope);
|
||||||
|
|
||||||
var AST_Accessor = DEFNODE("Accessor", null, {
|
var AST_Accessor = DEFNODE("Accessor", null, {
|
||||||
$documentation: "A setter/getter function. The `name` property is always null.",
|
$documentation: "A getter/setter function",
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
if (this.name != null) throw new Error("name must be null");
|
if (this.name != null) throw new Error("name must be null");
|
||||||
},
|
},
|
||||||
}, AST_Lambda);
|
}, AST_Lambda);
|
||||||
|
|
||||||
var AST_Function = DEFNODE("Function", "inlined", {
|
function is_arrow(node) {
|
||||||
$documentation: "A function expression",
|
return node instanceof AST_AsyncArrow || node instanceof AST_Arrow;
|
||||||
|
}
|
||||||
|
|
||||||
|
function is_function(node) {
|
||||||
|
return is_arrow(node) || node instanceof AST_AsyncFunction || node instanceof AST_Function;
|
||||||
|
}
|
||||||
|
|
||||||
|
function walk_lambda(node, tw) {
|
||||||
|
if (is_arrow(node) && node.value) {
|
||||||
|
node.value.walk(tw);
|
||||||
|
} else {
|
||||||
|
walk_body(node, tw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var AST_Arrow = DEFNODE("Arrow", "inlined value", {
|
||||||
|
$documentation: "An arrow function expression",
|
||||||
|
$propdoc: {
|
||||||
|
value: "[AST_Node?] simple return expression, or null if using function body.",
|
||||||
|
},
|
||||||
|
walk: function(visitor) {
|
||||||
|
var node = this;
|
||||||
|
visitor.visit(node, function() {
|
||||||
|
node.argnames.forEach(function(argname) {
|
||||||
|
argname.walk(visitor);
|
||||||
|
});
|
||||||
|
if (node.rest) node.rest.walk(visitor);
|
||||||
|
if (node.value) {
|
||||||
|
node.value.walk(visitor);
|
||||||
|
} else {
|
||||||
|
walk_body(node, visitor);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
_validate: function() {
|
||||||
|
if (this.name != null) throw new Error("name must be null");
|
||||||
|
if (this.uses_arguments) throw new Error("uses_arguments must be false");
|
||||||
|
if (this.value != null) {
|
||||||
|
must_be_expression(this, "value");
|
||||||
|
if (this.body.length) throw new Error("body must be empty if value exists");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}, AST_Lambda);
|
||||||
|
|
||||||
|
function is_async(node) {
|
||||||
|
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",
|
||||||
|
$propdoc: {
|
||||||
|
value: "[AST_Node?] simple return expression, or null if using function body.",
|
||||||
|
},
|
||||||
|
walk: function(visitor) {
|
||||||
|
var node = this;
|
||||||
|
visitor.visit(node, function() {
|
||||||
|
node.argnames.forEach(function(argname) {
|
||||||
|
argname.walk(visitor);
|
||||||
|
});
|
||||||
|
if (node.rest) node.rest.walk(visitor);
|
||||||
|
if (node.value) {
|
||||||
|
node.value.walk(visitor);
|
||||||
|
} else {
|
||||||
|
walk_body(node, visitor);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
_validate: function() {
|
||||||
|
if (this.name != null) throw new Error("name must be null");
|
||||||
|
if (this.uses_arguments) throw new Error("uses_arguments must be false");
|
||||||
|
if (this.value != null) {
|
||||||
|
must_be_expression(this, "value");
|
||||||
|
if (this.body.length) throw new Error("body must be empty if value exists");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}, AST_Lambda);
|
||||||
|
|
||||||
|
var AST_AsyncFunction = DEFNODE("AsyncFunction", "inlined name", {
|
||||||
|
$documentation: "An asynchronous function expression",
|
||||||
|
$propdoc: {
|
||||||
|
name: "[AST_SymbolLambda?] the name of this function",
|
||||||
|
},
|
||||||
_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");
|
||||||
@@ -554,8 +657,37 @@ var AST_Function = DEFNODE("Function", "inlined", {
|
|||||||
},
|
},
|
||||||
}, AST_Lambda);
|
}, AST_Lambda);
|
||||||
|
|
||||||
var AST_Defun = DEFNODE("Defun", "inlined", {
|
var AST_Function = DEFNODE("Function", "inlined name", {
|
||||||
|
$documentation: "A function expression",
|
||||||
|
$propdoc: {
|
||||||
|
name: "[AST_SymbolLambda?] the name of this function",
|
||||||
|
},
|
||||||
|
_validate: function() {
|
||||||
|
if (this.name != null) {
|
||||||
|
if (!(this.name instanceof AST_SymbolLambda)) throw new Error("name must be AST_SymbolLambda");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}, AST_Lambda);
|
||||||
|
|
||||||
|
function is_defun(node) {
|
||||||
|
return node instanceof AST_AsyncDefun || node instanceof AST_Defun;
|
||||||
|
}
|
||||||
|
|
||||||
|
var AST_AsyncDefun = DEFNODE("AsyncDefun", "inlined name", {
|
||||||
|
$documentation: "An asynchronous function definition",
|
||||||
|
$propdoc: {
|
||||||
|
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", {
|
||||||
$documentation: "A function definition",
|
$documentation: "A function definition",
|
||||||
|
$propdoc: {
|
||||||
|
name: "[AST_SymbolDefun] the name of this function",
|
||||||
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
if (!(this.name instanceof AST_SymbolDefun)) throw new Error("name must be AST_SymbolDefun");
|
if (!(this.name instanceof AST_SymbolDefun)) throw new Error("name must be AST_SymbolDefun");
|
||||||
},
|
},
|
||||||
@@ -640,7 +772,7 @@ var AST_If = DEFNODE("If", "condition alternative", {
|
|||||||
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 (!(this.alternative instanceof AST_Statement)) throw new Error("alternative must be AST_Statement");
|
||||||
if (this.alternative instanceof AST_Function) throw new error("alternative cannot be AST_Function");
|
if (is_function(this.alternative)) throw new error("alternative cannot be AST_Function");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}, AST_StatementWithBody);
|
}, AST_StatementWithBody);
|
||||||
@@ -721,7 +853,7 @@ var AST_Try = DEFNODE("Try", "bcatch bfinally", {
|
|||||||
var AST_Catch = DEFNODE("Catch", "argname", {
|
var AST_Catch = DEFNODE("Catch", "argname", {
|
||||||
$documentation: "A `catch` node; only makes sense as part of a `try` statement",
|
$documentation: "A `catch` node; only makes sense as part of a `try` statement",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
argname: "[AST_SymbolCatch?] symbol for the exception, or null if not present",
|
argname: "[(AST_Destructured|AST_SymbolCatch)?] symbol for the exception, or null if not present",
|
||||||
},
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
@@ -731,9 +863,9 @@ var AST_Catch = DEFNODE("Catch", "argname", {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
if (this.argname != null) {
|
if (this.argname != null) validate_destructured(this.argname, function(node) {
|
||||||
if (!(this.argname instanceof AST_SymbolCatch)) throw new Error("argname must be AST_SymbolCatch");
|
if (!(node instanceof AST_SymbolCatch)) throw new Error("argname must be AST_SymbolCatch");
|
||||||
}
|
});
|
||||||
},
|
},
|
||||||
}, AST_Block);
|
}, AST_Block);
|
||||||
|
|
||||||
@@ -769,7 +901,6 @@ var AST_Const = DEFNODE("Const", null, {
|
|||||||
validate_destructured(node.name, function(node) {
|
validate_destructured(node.name, function(node) {
|
||||||
if (!(node instanceof AST_SymbolConst)) throw new Error("name must be AST_SymbolConst");
|
if (!(node instanceof AST_SymbolConst)) throw new Error("name must be AST_SymbolConst");
|
||||||
});
|
});
|
||||||
if (node.value != null) must_be_expression(node, "value");
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
}, AST_Definitions);
|
}, AST_Definitions);
|
||||||
@@ -782,7 +913,6 @@ var AST_Let = DEFNODE("Let", null, {
|
|||||||
validate_destructured(node.name, function(node) {
|
validate_destructured(node.name, function(node) {
|
||||||
if (!(node instanceof AST_SymbolLet)) throw new Error("name must be AST_SymbolLet");
|
if (!(node instanceof AST_SymbolLet)) throw new Error("name must be AST_SymbolLet");
|
||||||
});
|
});
|
||||||
if (node.value != null) must_be_expression(node, "value");
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
}, AST_Definitions);
|
}, AST_Definitions);
|
||||||
@@ -795,7 +925,6 @@ var AST_Var = DEFNODE("Var", null, {
|
|||||||
validate_destructured(node.name, function(node) {
|
validate_destructured(node.name, function(node) {
|
||||||
if (!(node instanceof AST_SymbolVar)) throw new Error("name must be AST_SymbolVar");
|
if (!(node instanceof AST_SymbolVar)) throw new Error("name must be AST_SymbolVar");
|
||||||
});
|
});
|
||||||
if (node.value != null) must_be_expression(node, "value");
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
}, AST_Definitions);
|
}, AST_Definitions);
|
||||||
@@ -803,8 +932,8 @@ var AST_Var = DEFNODE("Var", null, {
|
|||||||
var AST_VarDef = DEFNODE("VarDef", "name value", {
|
var AST_VarDef = DEFNODE("VarDef", "name value", {
|
||||||
$documentation: "A variable declaration; only appears in a AST_Definitions node",
|
$documentation: "A variable declaration; only appears in a AST_Definitions node",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
name: "[AST_SymbolVar] name of the variable",
|
name: "[AST_Destructured|AST_SymbolVar] name of the variable",
|
||||||
value: "[AST_Node?] initializer, or null of there's no initializer"
|
value: "[AST_Node?] initializer, or null of there's no initializer",
|
||||||
},
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
@@ -813,16 +942,34 @@ var AST_VarDef = DEFNODE("VarDef", "name value", {
|
|||||||
if (node.value) node.value.walk(visitor);
|
if (node.value) node.value.walk(visitor);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
_validate: function() {
|
||||||
|
if (this.value != null) must_be_expression(this, "value");
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
/* -----[ OTHER ]----- */
|
/* -----[ OTHER ]----- */
|
||||||
|
|
||||||
function must_be_expressions(node, prop) {
|
var AST_DefaultValue = DEFNODE("DefaultValue", "name value", {
|
||||||
|
$documentation: "A default value declaration",
|
||||||
|
$propdoc: {
|
||||||
|
name: "[AST_Destructured|AST_SymbolDeclaration] name of the variable",
|
||||||
|
value: "[AST_Node] value to assign if variable is `undefined`",
|
||||||
|
},
|
||||||
|
walk: function(visitor) {
|
||||||
|
var node = this;
|
||||||
|
visitor.visit(node, function() {
|
||||||
|
node.name.walk(visitor);
|
||||||
|
node.value.walk(visitor);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
_validate: function() {
|
||||||
|
must_be_expression(this, "value");
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
function must_be_expressions(node, prop, allow_spread, allow_hole) {
|
||||||
node[prop].forEach(function(node) {
|
node[prop].forEach(function(node) {
|
||||||
if (!(node instanceof AST_Node)) throw new Error(prop + " must be AST_Node[]");
|
validate_expression(node, prop, true, allow_spread, allow_hole);
|
||||||
if (node instanceof AST_Statement && !(node instanceof AST_Function)) {
|
|
||||||
throw new Error(prop + " cannot contain AST_Statement");
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -843,7 +990,7 @@ var AST_Call = DEFNODE("Call", "expression args pure", {
|
|||||||
},
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
must_be_expression(this, "expression");
|
must_be_expression(this, "expression");
|
||||||
must_be_expressions(this, "args");
|
must_be_expressions(this, "args", true);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -920,6 +1067,22 @@ var AST_Sub = DEFNODE("Sub", null, {
|
|||||||
},
|
},
|
||||||
}, AST_PropAccess);
|
}, AST_PropAccess);
|
||||||
|
|
||||||
|
var AST_Spread = DEFNODE("Spread", "expression", {
|
||||||
|
$documentation: "Spread expression in array/object literals or function calls",
|
||||||
|
$propdoc: {
|
||||||
|
expression: "[AST_Node] expression to be expanded",
|
||||||
|
},
|
||||||
|
walk: function(visitor) {
|
||||||
|
var node = this;
|
||||||
|
visitor.visit(node, function() {
|
||||||
|
node.expression.walk(visitor);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
_validate: function() {
|
||||||
|
must_be_expression(this, "expression");
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
var AST_Unary = DEFNODE("Unary", "operator expression", {
|
var AST_Unary = DEFNODE("Unary", "operator expression", {
|
||||||
$documentation: "Base class for unary expressions",
|
$documentation: "Base class for unary expressions",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
@@ -961,7 +1124,7 @@ var AST_Binary = DEFNODE("Binary", "operator left right", {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
must_be_expression(this, "left");
|
if (!(this instanceof AST_Assign)) must_be_expression(this, "left");
|
||||||
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, "right");
|
must_be_expression(this, "right");
|
||||||
},
|
},
|
||||||
@@ -1004,6 +1167,22 @@ var AST_Assign = DEFNODE("Assign", null, {
|
|||||||
},
|
},
|
||||||
}, AST_Binary);
|
}, AST_Binary);
|
||||||
|
|
||||||
|
var AST_Await = DEFNODE("Await", "expression", {
|
||||||
|
$documentation: "An await expression",
|
||||||
|
$propdoc: {
|
||||||
|
expression: "[AST_Node] expression with Promise to resolve on",
|
||||||
|
},
|
||||||
|
walk: function(visitor) {
|
||||||
|
var node = this;
|
||||||
|
visitor.visit(node, function() {
|
||||||
|
node.expression.walk(visitor);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
_validate: function() {
|
||||||
|
must_be_expression(this, "expression");
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
/* -----[ LITERALS ]----- */
|
/* -----[ LITERALS ]----- */
|
||||||
|
|
||||||
var AST_Array = DEFNODE("Array", "elements", {
|
var AST_Array = DEFNODE("Array", "elements", {
|
||||||
@@ -1020,28 +1199,35 @@ var AST_Array = DEFNODE("Array", "elements", {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
must_be_expressions(this, "elements");
|
must_be_expressions(this, "elements", true, true);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
var AST_Destructured = DEFNODE("Destructured", null, {
|
var AST_Destructured = DEFNODE("Destructured", "rest", {
|
||||||
$documentation: "Base class for destructured literal",
|
$documentation: "Base class for destructured literal",
|
||||||
|
$propdoc: {
|
||||||
|
rest: "[(AST_Destructured|AST_SymbolDeclaration|AST_SymbolRef)?] rest parameter, or null if absent",
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
function validate_destructured(node, check) {
|
function validate_destructured(node, check, allow_default) {
|
||||||
if (node instanceof AST_DestructuredArray) return node.elements.forEach(function(node) {
|
if (node instanceof AST_DefaultValue && allow_default) return validate_destructured(node.name, check);
|
||||||
if (!(node instanceof AST_Hole)) validate_destructured(node, check);
|
if (node instanceof AST_Destructured) {
|
||||||
});
|
if (node.rest != null) validate_destructured(node.rest, check);
|
||||||
if (node instanceof AST_DestructuredObject) return node.properties.forEach(function(prop) {
|
if (node instanceof AST_DestructuredArray) return node.elements.forEach(function(node) {
|
||||||
validate_destructured(prop.value, check);
|
if (!(node instanceof AST_Hole)) validate_destructured(node, check, true);
|
||||||
});
|
});
|
||||||
|
if (node instanceof AST_DestructuredObject) return node.properties.forEach(function(prop) {
|
||||||
|
validate_destructured(prop.value, check, true);
|
||||||
|
});
|
||||||
|
}
|
||||||
check(node);
|
check(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
var AST_DestructuredArray = DEFNODE("DestructuredArray", "elements", {
|
var AST_DestructuredArray = DEFNODE("DestructuredArray", "elements", {
|
||||||
$documentation: "A destructured array literal",
|
$documentation: "A destructured array literal",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
elements: "[AST_Node*] array of elements",
|
elements: "[(AST_DefaultValue|AST_Destructured|AST_SymbolDeclaration|AST_SymbolRef)*] array of elements",
|
||||||
},
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
@@ -1049,6 +1235,7 @@ var AST_DestructuredArray = DEFNODE("DestructuredArray", "elements", {
|
|||||||
node.elements.forEach(function(element) {
|
node.elements.forEach(function(element) {
|
||||||
element.walk(visitor);
|
element.walk(visitor);
|
||||||
});
|
});
|
||||||
|
if (node.rest) node.rest.walk(visitor);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
}, AST_Destructured);
|
}, AST_Destructured);
|
||||||
@@ -1057,7 +1244,7 @@ var AST_DestructuredKeyVal = DEFNODE("DestructuredKeyVal", "key value", {
|
|||||||
$documentation: "A key: value destructured property",
|
$documentation: "A key: value destructured property",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
key: "[string|AST_Node] property name. For computed property this is an AST_Node.",
|
key: "[string|AST_Node] property name. For computed property this is an AST_Node.",
|
||||||
value: "[AST_Node] property value",
|
value: "[AST_DefaultValue|AST_Destructured|AST_SymbolDeclaration|AST_SymbolRef] property value",
|
||||||
},
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
@@ -1071,7 +1258,7 @@ var AST_DestructuredKeyVal = DEFNODE("DestructuredKeyVal", "key value", {
|
|||||||
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");
|
||||||
}
|
}
|
||||||
must_be_expression(this, "value");
|
if (!(this.value instanceof AST_Node)) throw new Error("value must be AST_Node");
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1086,6 +1273,7 @@ var AST_DestructuredObject = DEFNODE("DestructuredObject", "properties", {
|
|||||||
node.properties.forEach(function(prop) {
|
node.properties.forEach(function(prop) {
|
||||||
prop.walk(visitor);
|
prop.walk(visitor);
|
||||||
});
|
});
|
||||||
|
if (node.rest) node.rest.walk(visitor);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
@@ -1098,7 +1286,7 @@ var AST_DestructuredObject = DEFNODE("DestructuredObject", "properties", {
|
|||||||
var AST_Object = DEFNODE("Object", "properties", {
|
var AST_Object = DEFNODE("Object", "properties", {
|
||||||
$documentation: "An object literal",
|
$documentation: "An object literal",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
properties: "[AST_ObjectProperty*] array of properties"
|
properties: "[(AST_ObjectProperty|AST_Spread)*] array of properties"
|
||||||
},
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
@@ -1110,7 +1298,9 @@ var AST_Object = DEFNODE("Object", "properties", {
|
|||||||
},
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
this.properties.forEach(function(node) {
|
this.properties.forEach(function(node) {
|
||||||
if (!(node instanceof AST_ObjectProperty)) throw new Error("properties must be AST_ObjectProperty[]");
|
if (!(node instanceof AST_ObjectProperty || node instanceof AST_Spread)) {
|
||||||
|
throw new Error("properties must contain AST_ObjectProperty and/or AST_Spread only");
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -1213,7 +1403,7 @@ var AST_Label = DEFNODE("Label", "references", {
|
|||||||
}
|
}
|
||||||
}, AST_Symbol);
|
}, AST_Symbol);
|
||||||
|
|
||||||
var AST_SymbolRef = DEFNODE("SymbolRef", "fixed", {
|
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);
|
||||||
|
|
||||||
@@ -1250,6 +1440,19 @@ var AST_Number = DEFNODE("Number", "value", {
|
|||||||
},
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
if (typeof this.value != "number") throw new Error("value must be number");
|
if (typeof this.value != "number") throw new Error("value must be number");
|
||||||
|
if (!isFinite(this.value)) throw new Error("value must be finite");
|
||||||
|
if (this.value < 0) throw new Error("value cannot be negative");
|
||||||
|
},
|
||||||
|
}, AST_Constant);
|
||||||
|
|
||||||
|
var AST_BigInt = DEFNODE("BigInt", "value", {
|
||||||
|
$documentation: "A BigInt literal",
|
||||||
|
$propdoc: {
|
||||||
|
value: "[string] the numeric representation",
|
||||||
|
},
|
||||||
|
_validate: function() {
|
||||||
|
if (typeof this.value != "string") throw new Error("value must be string");
|
||||||
|
if (this.value[0] == "-") throw new Error("value cannot be negative");
|
||||||
},
|
},
|
||||||
}, AST_Constant);
|
}, AST_Constant);
|
||||||
|
|
||||||
@@ -1389,14 +1592,13 @@ TreeWalker.prototype = {
|
|||||||
|| p.tail_node() === self) {
|
|| p.tail_node() === self) {
|
||||||
self = p;
|
self = p;
|
||||||
} else if (p instanceof AST_Return) {
|
} else if (p instanceof AST_Return) {
|
||||||
var fn;
|
for (var call, fn = p; call = this.parent(++i); fn = call) {
|
||||||
do {
|
if (call.TYPE == "Call") {
|
||||||
fn = this.parent(++i);
|
if (!(fn instanceof AST_Lambda) || fn.name) return false;
|
||||||
if (!fn) return false;
|
} else if (fn instanceof AST_Lambda) {
|
||||||
} while (!(fn instanceof AST_Lambda));
|
return false;
|
||||||
if (fn.name) return false;
|
}
|
||||||
self = this.parent(++i);
|
}
|
||||||
if (!self || self.TYPE != "Call" || self.expression !== fn) return false;
|
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
2562
lib/compress.js
2562
lib/compress.js
File diff suppressed because it is too large
Load Diff
@@ -87,6 +87,7 @@ function minify(files, options) {
|
|||||||
sourceMap: false,
|
sourceMap: false,
|
||||||
timings: false,
|
timings: false,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
|
v8: false,
|
||||||
validate: false,
|
validate: false,
|
||||||
warnings: false,
|
warnings: false,
|
||||||
webkit: false,
|
webkit: false,
|
||||||
@@ -102,6 +103,7 @@ function minify(files, options) {
|
|||||||
set_shorthand("ie8", options, [ "compress", "mangle", "output" ]);
|
set_shorthand("ie8", options, [ "compress", "mangle", "output" ]);
|
||||||
set_shorthand("keep_fnames", options, [ "compress", "mangle" ]);
|
set_shorthand("keep_fnames", options, [ "compress", "mangle" ]);
|
||||||
set_shorthand("toplevel", options, [ "compress", "mangle" ]);
|
set_shorthand("toplevel", options, [ "compress", "mangle" ]);
|
||||||
|
set_shorthand("v8", options, [ "mangle", "output" ]);
|
||||||
set_shorthand("webkit", options, [ "mangle", "output" ]);
|
set_shorthand("webkit", options, [ "mangle", "output" ]);
|
||||||
var quoted_props;
|
var quoted_props;
|
||||||
if (options.mangle) {
|
if (options.mangle) {
|
||||||
@@ -113,6 +115,7 @@ function minify(files, options) {
|
|||||||
properties: false,
|
properties: false,
|
||||||
reserved: [],
|
reserved: [],
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
|
v8: false,
|
||||||
webkit: false,
|
webkit: false,
|
||||||
}, true);
|
}, true);
|
||||||
if (options.mangle.properties) {
|
if (options.mangle.properties) {
|
||||||
|
|||||||
190
lib/output.js
190
lib/output.js
@@ -661,7 +661,7 @@ function OutputStream(options) {
|
|||||||
|
|
||||||
// a function expression needs parens around it when it's provably
|
// a function expression needs parens around it when it's provably
|
||||||
// the first token to appear in a statement.
|
// the first token to appear in a statement.
|
||||||
PARENS(AST_Function, function(output) {
|
function needs_parens_function(output) {
|
||||||
if (!output.has_parens() && first_in_statement(output)) return true;
|
if (!output.has_parens() && first_in_statement(output)) return true;
|
||||||
if (output.option("webkit")) {
|
if (output.option("webkit")) {
|
||||||
var p = output.parent();
|
var p = output.parent();
|
||||||
@@ -671,50 +671,69 @@ function OutputStream(options) {
|
|||||||
var p = output.parent();
|
var p = output.parent();
|
||||||
if (p instanceof AST_Call && p.expression === this) return true;
|
if (p instanceof AST_Call && p.expression === this) return true;
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
PARENS(AST_AsyncFunction, needs_parens_function);
|
||||||
|
PARENS(AST_Function, needs_parens_function);
|
||||||
|
|
||||||
// same goes for an object literal, because otherwise it would be
|
// same goes for an object literal, because otherwise it would be
|
||||||
// interpreted as a block of code.
|
// interpreted as a block of code.
|
||||||
function needs_parens_obj(output) {
|
function needs_parens_obj(output) {
|
||||||
return !output.has_parens() && first_in_statement(output);
|
return !output.has_parens() && first_in_statement(output, true);
|
||||||
}
|
}
|
||||||
PARENS(AST_Object, needs_parens_obj);
|
PARENS(AST_Object, needs_parens_obj);
|
||||||
|
|
||||||
PARENS(AST_Unary, function(output) {
|
PARENS(AST_Unary, function(output) {
|
||||||
var p = output.parent();
|
var p = output.parent();
|
||||||
|
// (-x) ** y
|
||||||
|
if (p instanceof AST_Binary) return p.operator == "**" && p.left === this;
|
||||||
|
// (x++).toString(3)
|
||||||
|
// (typeof x).length
|
||||||
return (p instanceof AST_Call || p instanceof AST_PropAccess) && p.expression === this;
|
return (p instanceof AST_Call || p instanceof AST_PropAccess) && p.expression === this;
|
||||||
});
|
});
|
||||||
|
|
||||||
PARENS(AST_Sequence, function(output) {
|
PARENS(AST_Sequence, function(output) {
|
||||||
var p = output.parent();
|
var p = output.parent();
|
||||||
// [ 1, (2, 3), 4 ] ==> [ 1, 3, 4 ]
|
// [ 1, (2, 3), 4 ] ---> [ 1, 3, 4 ]
|
||||||
return p instanceof AST_Array
|
return p instanceof AST_Array
|
||||||
// 1 + (2, 3) + 4 ==> 8
|
// () ---> (foo, bar)
|
||||||
|
|| is_arrow(p) && p.value === this
|
||||||
|
// await (foo, bar)
|
||||||
|
|| p instanceof AST_Await
|
||||||
|
// 1 + (2, 3) + 4 ---> 8
|
||||||
|| p instanceof AST_Binary
|
|| p instanceof AST_Binary
|
||||||
// new (foo, bar) or foo(1, (2, 3), 4)
|
// new (foo, bar) or foo(1, (2, 3), 4)
|
||||||
|| p instanceof AST_Call
|
|| p instanceof AST_Call
|
||||||
// (false, true) ? (a = 10, b = 20) : (c = 30)
|
// (false, true) ? (a = 10, b = 20) : (c = 30)
|
||||||
// ==> 20 (side effect, set a := 10 and b := 20)
|
// ---> 20 (side effect, set a := 10 and b := 20)
|
||||||
|| p instanceof AST_Conditional
|
|| p instanceof AST_Conditional
|
||||||
// { [(1, 2)]: 3 }[2] ==> 3
|
// [ a = (1, 2) ] = [] ---> a == 2
|
||||||
// { foo: (1, 2) }.foo ==> 2
|
|| p instanceof AST_DefaultValue
|
||||||
|
// { [(1, 2)]: 3 }[2] ---> 3
|
||||||
|
// { foo: (1, 2) }.foo ---> 2
|
||||||
|| p instanceof AST_DestructuredKeyVal
|
|| p instanceof AST_DestructuredKeyVal
|
||||||
|| p instanceof AST_ObjectProperty
|
|| p instanceof AST_ObjectProperty
|
||||||
// (1, {foo:2}).foo or (1, {foo:2})["foo"] ==> 2
|
// (1, {foo:2}).foo or (1, {foo:2})["foo"] ---> 2
|
||||||
|| p instanceof AST_PropAccess && p.expression === this
|
|| p instanceof AST_PropAccess && p.expression === this
|
||||||
|
// ...(foo, bar, baz)
|
||||||
|
|| p instanceof AST_Spread
|
||||||
// !(foo, bar, baz)
|
// !(foo, bar, baz)
|
||||||
|| p instanceof AST_Unary
|
|| p instanceof AST_Unary
|
||||||
// var a = (1, 2), b = a + a; ==> b == 4
|
// var a = (1, 2), b = a + a; ---> b == 4
|
||||||
|| p instanceof AST_VarDef;
|
|| p instanceof AST_VarDef;
|
||||||
});
|
});
|
||||||
|
|
||||||
PARENS(AST_Binary, function(output) {
|
PARENS(AST_Binary, function(output) {
|
||||||
var p = output.parent();
|
var p = output.parent();
|
||||||
// this deals with precedence: 3 * (2 + 1)
|
// await (foo && bar)
|
||||||
|
if (p instanceof AST_Await) return true;
|
||||||
|
// this deals with precedence:
|
||||||
|
// 3 * (2 + 1)
|
||||||
|
// 3 - (2 - 1)
|
||||||
|
// (1 ** 2) ** 3
|
||||||
if (p instanceof AST_Binary) {
|
if (p instanceof AST_Binary) {
|
||||||
var po = p.operator, pp = PRECEDENCE[po];
|
var po = p.operator, pp = PRECEDENCE[po];
|
||||||
var so = this.operator, sp = PRECEDENCE[so];
|
var so = this.operator, sp = PRECEDENCE[so];
|
||||||
return pp > sp || (pp == sp && this === p.right);
|
return pp > sp || (pp == sp && this === p[po == "**" ? "left" : "right"]);
|
||||||
}
|
}
|
||||||
// (foo && bar)()
|
// (foo && bar)()
|
||||||
if (p instanceof AST_Call) return p.expression === this;
|
if (p instanceof AST_Call) return p.expression === this;
|
||||||
@@ -765,18 +784,16 @@ function OutputStream(options) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
PARENS(AST_Number, function(output) {
|
PARENS(AST_Number, function(output) {
|
||||||
|
if (!output.option("galio")) return false;
|
||||||
|
// https://github.com/mishoo/UglifyJS/pull/1009
|
||||||
var p = output.parent();
|
var p = output.parent();
|
||||||
if (p instanceof AST_PropAccess && p.expression === this) {
|
return p instanceof AST_PropAccess && p.expression === this && /^0/.test(make_num(this.value));
|
||||||
var value = this.value;
|
|
||||||
// https://github.com/mishoo/UglifyJS/issues/115
|
|
||||||
return value < 0
|
|
||||||
// https://github.com/mishoo/UglifyJS/pull/1009
|
|
||||||
|| output.option("galio") && /^0/.test(make_num(value));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function needs_parens_assign_cond(self, output) {
|
function needs_parens_assign_cond(self, output) {
|
||||||
var p = output.parent();
|
var p = output.parent();
|
||||||
|
// await (a = foo)
|
||||||
|
if (p instanceof AST_Await) return true;
|
||||||
// 1 + (a = 2) + 3 → 6, side effect setting a = 2
|
// 1 + (a = 2) + 3 → 6, side effect setting a = 2
|
||||||
if (p instanceof AST_Binary) return !(p instanceof AST_Assign);
|
if (p instanceof AST_Binary) return !(p instanceof AST_Assign);
|
||||||
// (a = func)() —or— new (a = Object)()
|
// (a = func)() —or— new (a = Object)()
|
||||||
@@ -788,18 +805,36 @@ function OutputStream(options) {
|
|||||||
// !(a = false) → true
|
// !(a = false) → true
|
||||||
if (p instanceof AST_Unary) return true;
|
if (p instanceof AST_Unary) return true;
|
||||||
}
|
}
|
||||||
|
PARENS(AST_Arrow, function(output) {
|
||||||
|
return needs_parens_assign_cond(this, output);
|
||||||
|
});
|
||||||
PARENS(AST_Assign, function(output) {
|
PARENS(AST_Assign, function(output) {
|
||||||
if (needs_parens_assign_cond(this, output)) return true;
|
if (needs_parens_assign_cond(this, output)) return true;
|
||||||
// v8 parser bug => workaround
|
// v8 parser bug ---> workaround
|
||||||
// f([1], [a] = []) => f([1], ([a] = []))
|
// f([1], [a] = []) ---> f([1], ([a] = []))
|
||||||
if (output.option("v8")) return this.left instanceof AST_Destructured;
|
if (output.option("v8")) return this.left instanceof AST_Destructured;
|
||||||
// ({ p: a } = o);
|
// ({ p: a } = o);
|
||||||
if (this.left instanceof AST_DestructuredObject) return needs_parens_obj(output);
|
if (this.left instanceof AST_DestructuredObject) return needs_parens_obj(output);
|
||||||
});
|
});
|
||||||
|
PARENS(AST_AsyncArrow, function(output) {
|
||||||
|
return needs_parens_assign_cond(this, output);
|
||||||
|
});
|
||||||
PARENS(AST_Conditional, function(output) {
|
PARENS(AST_Conditional, function(output) {
|
||||||
return needs_parens_assign_cond(this, output);
|
return needs_parens_assign_cond(this, output);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
PARENS(AST_Await, function(output) {
|
||||||
|
var p = output.parent();
|
||||||
|
// (await x) ** y
|
||||||
|
if (p instanceof AST_Binary) return p.operator == "**" && p.left === this;
|
||||||
|
// new (await foo)
|
||||||
|
// (await foo)(bar)
|
||||||
|
if (p instanceof AST_Call) return p.expression === this;
|
||||||
|
// (await foo).prop
|
||||||
|
// (await foo)["prop"]
|
||||||
|
if (p instanceof AST_PropAccess) return p.expression === this;
|
||||||
|
});
|
||||||
|
|
||||||
/* -----[ PRINTERS ]----- */
|
/* -----[ PRINTERS ]----- */
|
||||||
|
|
||||||
DEFPRINT(AST_Directive, function(output) {
|
DEFPRINT(AST_Directive, function(output) {
|
||||||
@@ -965,24 +1000,63 @@ function OutputStream(options) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
/* -----[ functions ]----- */
|
/* -----[ functions ]----- */
|
||||||
DEFPRINT(AST_Lambda, function(output, nokeyword) {
|
function print_funargs(self, output) {
|
||||||
var self = this;
|
|
||||||
if (!nokeyword) {
|
|
||||||
output.print("function");
|
|
||||||
}
|
|
||||||
if (self.name) {
|
|
||||||
output.space();
|
|
||||||
self.name.print(output);
|
|
||||||
}
|
|
||||||
output.with_parens(function() {
|
output.with_parens(function() {
|
||||||
self.argnames.forEach(function(arg, i) {
|
self.argnames.forEach(function(arg, i) {
|
||||||
if (i) output.comma();
|
if (i) output.comma();
|
||||||
arg.print(output);
|
arg.print(output);
|
||||||
});
|
});
|
||||||
|
if (self.rest) {
|
||||||
|
if (self.argnames.length) output.comma();
|
||||||
|
output.print("...");
|
||||||
|
self.rest.print(output);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
function print_arrow(self, output) {
|
||||||
|
if (self.argnames.length == 1 && self.argnames[0] instanceof AST_SymbolFunarg && !self.rest) {
|
||||||
|
self.argnames[0].print(output);
|
||||||
|
} else {
|
||||||
|
print_funargs(self, output);
|
||||||
|
}
|
||||||
|
output.space();
|
||||||
|
output.print("=>");
|
||||||
|
output.space();
|
||||||
|
if (self.value) {
|
||||||
|
self.value.print(output);
|
||||||
|
} else {
|
||||||
|
print_braced(self, output, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DEFPRINT(AST_Arrow, function(output) {
|
||||||
|
print_arrow(this, output);
|
||||||
|
});
|
||||||
|
DEFPRINT(AST_AsyncArrow, function(output) {
|
||||||
|
output.print("async");
|
||||||
|
output.space();
|
||||||
|
print_arrow(this, output);
|
||||||
|
});
|
||||||
|
function print_lambda(self, output) {
|
||||||
|
if (self.name) {
|
||||||
|
output.space();
|
||||||
|
self.name.print(output);
|
||||||
|
}
|
||||||
|
print_funargs(self, output);
|
||||||
output.space();
|
output.space();
|
||||||
print_braced(self, output, true);
|
print_braced(self, output, true);
|
||||||
|
}
|
||||||
|
DEFPRINT(AST_Lambda, function(output) {
|
||||||
|
output.print("function");
|
||||||
|
print_lambda(this, output);
|
||||||
});
|
});
|
||||||
|
function print_async(output) {
|
||||||
|
output.print("async");
|
||||||
|
output.space();
|
||||||
|
output.print("function");
|
||||||
|
print_lambda(this, output);
|
||||||
|
}
|
||||||
|
DEFPRINT(AST_AsyncDefun, print_async);
|
||||||
|
DEFPRINT(AST_AsyncFunction, print_async);
|
||||||
|
|
||||||
/* -----[ jumps ]----- */
|
/* -----[ jumps ]----- */
|
||||||
function print_jump(kind, prop) {
|
function print_jump(kind, prop) {
|
||||||
@@ -1146,11 +1220,9 @@ function OutputStream(options) {
|
|||||||
// need to take some precautions here:
|
// need to take some precautions here:
|
||||||
// https://github.com/mishoo/UglifyJS/issues/60
|
// https://github.com/mishoo/UglifyJS/issues/60
|
||||||
if (noin) node.walk(new TreeWalker(function(node) {
|
if (noin) node.walk(new TreeWalker(function(node) {
|
||||||
if (parens || node instanceof AST_Scope) return true;
|
if (parens) return true;
|
||||||
if (node instanceof AST_Binary && node.operator == "in") {
|
if (node instanceof AST_Binary && node.operator == "in") return parens = true;
|
||||||
parens = true;
|
if (node instanceof AST_Scope && !(is_arrow(node) && node.value)) return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}));
|
}));
|
||||||
node.print(output, parens);
|
node.print(output, parens);
|
||||||
}
|
}
|
||||||
@@ -1168,6 +1240,15 @@ function OutputStream(options) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
DEFPRINT(AST_DefaultValue, function(output) {
|
||||||
|
var self = this;
|
||||||
|
self.name.print(output);
|
||||||
|
output.space();
|
||||||
|
output.print("=");
|
||||||
|
output.space();
|
||||||
|
self.value.print(output);
|
||||||
|
});
|
||||||
|
|
||||||
/* -----[ other expressions ]----- */
|
/* -----[ other expressions ]----- */
|
||||||
function print_call_args(self, output) {
|
function print_call_args(self, output) {
|
||||||
if (self.expression instanceof AST_Call || self.expression instanceof AST_Lambda) {
|
if (self.expression instanceof AST_Call || self.expression instanceof AST_Lambda) {
|
||||||
@@ -1231,6 +1312,10 @@ function OutputStream(options) {
|
|||||||
this.property.print(output);
|
this.property.print(output);
|
||||||
output.print("]");
|
output.print("]");
|
||||||
});
|
});
|
||||||
|
DEFPRINT(AST_Spread, function(output) {
|
||||||
|
output.print("...");
|
||||||
|
this.expression.print(output);
|
||||||
|
});
|
||||||
DEFPRINT(AST_UnaryPrefix, function(output) {
|
DEFPRINT(AST_UnaryPrefix, function(output) {
|
||||||
var op = this.operator;
|
var op = this.operator;
|
||||||
var exp = this.expression;
|
var exp = this.expression;
|
||||||
@@ -1266,6 +1351,11 @@ function OutputStream(options) {
|
|||||||
output.colon();
|
output.colon();
|
||||||
self.alternative.print(output);
|
self.alternative.print(output);
|
||||||
});
|
});
|
||||||
|
DEFPRINT(AST_Await, function(output) {
|
||||||
|
output.print("await");
|
||||||
|
output.space();
|
||||||
|
this.expression.print(output);
|
||||||
|
});
|
||||||
|
|
||||||
/* -----[ literals ]----- */
|
/* -----[ literals ]----- */
|
||||||
DEFPRINT(AST_Array, function(output) {
|
DEFPRINT(AST_Array, function(output) {
|
||||||
@@ -1285,25 +1375,30 @@ function OutputStream(options) {
|
|||||||
} : noop);
|
} : noop);
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_DestructuredArray, function(output) {
|
DEFPRINT(AST_DestructuredArray, function(output) {
|
||||||
var a = this.elements, len = a.length;
|
var a = this.elements, len = a.length, rest = this.rest;
|
||||||
output.with_square(len > 0 ? function() {
|
output.with_square(len || rest ? function() {
|
||||||
output.space();
|
output.space();
|
||||||
a.forEach(function(exp, i) {
|
a.forEach(function(exp, i) {
|
||||||
if (i) output.comma();
|
if (i) output.comma();
|
||||||
exp.print(output);
|
exp.print(output);
|
||||||
|
});
|
||||||
|
if (rest) {
|
||||||
|
if (len) output.comma();
|
||||||
|
output.print("...");
|
||||||
|
rest.print(output);
|
||||||
|
} else if (a[len - 1] instanceof AST_Hole) {
|
||||||
// If the final element is a hole, we need to make sure it
|
// If the final element is a hole, we need to make sure it
|
||||||
// doesn't look like a trailing comma, by inserting an actual
|
// doesn't look like a trailing comma, by inserting an actual
|
||||||
// trailing comma.
|
// trailing comma.
|
||||||
if (i === len - 1 && exp instanceof AST_Hole)
|
output.comma();
|
||||||
output.comma();
|
}
|
||||||
});
|
|
||||||
output.space();
|
output.space();
|
||||||
} : noop);
|
} : noop);
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_DestructuredKeyVal, print_key_value);
|
DEFPRINT(AST_DestructuredKeyVal, print_key_value);
|
||||||
DEFPRINT(AST_DestructuredObject, function(output) {
|
DEFPRINT(AST_DestructuredObject, function(output) {
|
||||||
var props = this.properties;
|
var props = this.properties, len = props.length, rest = this.rest;
|
||||||
if (props.length > 0) output.with_block(function() {
|
if (len || rest) output.with_block(function() {
|
||||||
props.forEach(function(prop, i) {
|
props.forEach(function(prop, i) {
|
||||||
if (i) {
|
if (i) {
|
||||||
output.print(",");
|
output.print(",");
|
||||||
@@ -1312,6 +1407,15 @@ function OutputStream(options) {
|
|||||||
output.indent();
|
output.indent();
|
||||||
prop.print(output);
|
prop.print(output);
|
||||||
});
|
});
|
||||||
|
if (rest) {
|
||||||
|
if (len) {
|
||||||
|
output.print(",");
|
||||||
|
output.newline();
|
||||||
|
}
|
||||||
|
output.indent();
|
||||||
|
output.print("...");
|
||||||
|
rest.print(output);
|
||||||
|
}
|
||||||
output.newline();
|
output.newline();
|
||||||
});
|
});
|
||||||
else print_braced_empty(this, output);
|
else print_braced_empty(this, output);
|
||||||
@@ -1369,7 +1473,7 @@ function OutputStream(options) {
|
|||||||
output.print(type);
|
output.print(type);
|
||||||
output.space();
|
output.space();
|
||||||
print_property_key(self, output);
|
print_property_key(self, output);
|
||||||
self.value._codegen(output, true);
|
print_lambda(self.value, output);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
DEFPRINT(AST_ObjectGetter, print_accessor("get"));
|
DEFPRINT(AST_ObjectGetter, print_accessor("get"));
|
||||||
|
|||||||
538
lib/parse.js
538
lib/parse.js
@@ -47,7 +47,7 @@
|
|||||||
var KEYWORDS = "break case catch const continue debugger default delete do else finally for function if in instanceof let new return switch throw try typeof var void while with";
|
var KEYWORDS = "break case catch const continue debugger default delete do else finally for function if in instanceof let new return switch throw try typeof var void while with";
|
||||||
var KEYWORDS_ATOM = "false null true";
|
var KEYWORDS_ATOM = "false null true";
|
||||||
var RESERVED_WORDS = [
|
var RESERVED_WORDS = [
|
||||||
"abstract boolean byte char class double enum export extends final float goto implements import int interface let long native package private protected public short static super synchronized this throws transient volatile yield",
|
"await abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized this throws transient volatile yield",
|
||||||
KEYWORDS_ATOM,
|
KEYWORDS_ATOM,
|
||||||
KEYWORDS,
|
KEYWORDS,
|
||||||
].join(" ");
|
].join(" ");
|
||||||
@@ -81,6 +81,7 @@ var OPERATORS = makePredicate([
|
|||||||
"*",
|
"*",
|
||||||
"/",
|
"/",
|
||||||
"%",
|
"%",
|
||||||
|
"**",
|
||||||
">>",
|
">>",
|
||||||
"<<",
|
"<<",
|
||||||
">>>",
|
">>>",
|
||||||
@@ -280,9 +281,8 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function read_while(pred) {
|
function read_while(pred) {
|
||||||
var ret = "", ch, i = 0;
|
var ret = "", ch;
|
||||||
while ((ch = peek()) && pred(ch, i++))
|
while ((ch = peek()) && pred(ch)) ret += next();
|
||||||
ret += next();
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,16 +292,14 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
|
|
||||||
function read_num(prefix) {
|
function read_num(prefix) {
|
||||||
var has_e = false, after_e = false, has_x = false, has_dot = prefix == ".";
|
var has_e = false, after_e = false, has_x = false, has_dot = prefix == ".";
|
||||||
var num = read_while(function(ch, i) {
|
var num = read_while(function(ch) {
|
||||||
var code = ch.charCodeAt(0);
|
var code = ch.charCodeAt(0);
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case 120: case 88: // xX
|
case 120: case 88: // xX
|
||||||
return has_x ? false : (has_x = true);
|
return has_x ? false : (has_x = true);
|
||||||
case 101: case 69: // eE
|
case 101: case 69: // eE
|
||||||
return has_x ? true : has_e ? false : (has_e = after_e = true);
|
return has_x ? true : has_e ? false : (has_e = after_e = true);
|
||||||
case 45: // -
|
case 43: case 45: // +-
|
||||||
return after_e || (i == 0 && !prefix);
|
|
||||||
case 43: // +
|
|
||||||
return after_e;
|
return after_e;
|
||||||
case (after_e = false, 46): // .
|
case (after_e = false, 46): // .
|
||||||
return (!has_dot && !has_x && !has_e) ? (has_dot = true) : false;
|
return (!has_dot && !has_x && !has_e) ? (has_dot = true) : false;
|
||||||
@@ -315,8 +313,9 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
num = num.replace(has_x ? /([1-9a-f]|.0)_(?=[0-9a-f])/gi : /([1-9]|.0)_(?=[0-9])/gi, "$1");
|
num = num.replace(has_x ? /([1-9a-f]|.0)_(?=[0-9a-f])/gi : /([1-9]|.0)_(?=[0-9])/gi, "$1");
|
||||||
}
|
}
|
||||||
var valid = parse_js_number(num);
|
var valid = parse_js_number(num);
|
||||||
if (!isNaN(valid)) return token("num", valid);
|
if (isNaN(valid)) parse_error("Invalid syntax: " + num);
|
||||||
parse_error("Invalid syntax: " + num);
|
if (has_dot || has_e || peek() != "n") return token("num", valid);
|
||||||
|
return token("bigint", num.toLowerCase() + next());
|
||||||
}
|
}
|
||||||
|
|
||||||
function read_escaped_char(in_string) {
|
function read_escaped_char(in_string) {
|
||||||
@@ -501,7 +500,16 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
|
|
||||||
function handle_dot() {
|
function handle_dot() {
|
||||||
next();
|
next();
|
||||||
return is_digit(peek().charCodeAt(0)) ? read_num(".") : token("punc", ".");
|
var ch = peek();
|
||||||
|
if (ch == ".") {
|
||||||
|
var op = ".";
|
||||||
|
do {
|
||||||
|
op += ".";
|
||||||
|
next();
|
||||||
|
} while (peek() == ".");
|
||||||
|
return token("operator", op);
|
||||||
|
}
|
||||||
|
return is_digit(ch.charCodeAt(0)) ? read_num(".") : token("punc", ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
function read_word() {
|
function read_word() {
|
||||||
@@ -560,6 +568,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
}
|
}
|
||||||
if (is_digit(code)) return read_num();
|
if (is_digit(code)) return read_num();
|
||||||
if (PUNC_CHARS[ch]) return token("punc", next());
|
if (PUNC_CHARS[ch]) return token("punc", next());
|
||||||
|
if (looking_at("=>")) return token("punc", next() + next());
|
||||||
if (OPERATOR_CHARS[ch]) return read_operator();
|
if (OPERATOR_CHARS[ch]) return read_operator();
|
||||||
if (code == 92 || !NON_IDENTIFIER_CHARS[ch]) return read_word();
|
if (code == 92 || !NON_IDENTIFIER_CHARS[ch]) return read_word();
|
||||||
break;
|
break;
|
||||||
@@ -622,10 +631,11 @@ var PRECEDENCE = function(a, ret) {
|
|||||||
["<", ">", "<=", ">=", "in", "instanceof"],
|
["<", ">", "<=", ">=", "in", "instanceof"],
|
||||||
[">>", "<<", ">>>"],
|
[">>", "<<", ">>>"],
|
||||||
["+", "-"],
|
["+", "-"],
|
||||||
["*", "/", "%"]
|
["*", "/", "%"],
|
||||||
|
["**"],
|
||||||
], {});
|
], {});
|
||||||
|
|
||||||
var ATOMIC_START_TOKEN = makePredicate("atom num string regexp name");
|
var ATOMIC_START_TOKEN = makePredicate("atom bigint num regexp string");
|
||||||
|
|
||||||
/* -----[ Parser ]----- */
|
/* -----[ Parser ]----- */
|
||||||
|
|
||||||
@@ -644,13 +654,15 @@ function parse($TEXT, options) {
|
|||||||
input : typeof $TEXT == "string"
|
input : typeof $TEXT == "string"
|
||||||
? tokenizer($TEXT, options.filename, options.html5_comments, options.shebang)
|
? tokenizer($TEXT, options.filename, options.html5_comments, options.shebang)
|
||||||
: $TEXT,
|
: $TEXT,
|
||||||
token : null,
|
in_async : false,
|
||||||
prev : null,
|
|
||||||
peeked : null,
|
|
||||||
in_function : 0,
|
|
||||||
in_directives : true,
|
in_directives : true,
|
||||||
|
in_funarg : -1,
|
||||||
|
in_function : 0,
|
||||||
in_loop : 0,
|
in_loop : 0,
|
||||||
labels : []
|
labels : [],
|
||||||
|
peeked : null,
|
||||||
|
prev : null,
|
||||||
|
token : null,
|
||||||
};
|
};
|
||||||
|
|
||||||
S.token = next();
|
S.token = next();
|
||||||
@@ -725,12 +737,12 @@ function parse($TEXT, options) {
|
|||||||
|
|
||||||
function semicolon(optional) {
|
function semicolon(optional) {
|
||||||
if (is("punc", ";")) next();
|
if (is("punc", ";")) next();
|
||||||
else if (!optional && !can_insert_semicolon()) expect_token("punc", ";");
|
else if (!optional && !can_insert_semicolon()) expect(";");
|
||||||
}
|
}
|
||||||
|
|
||||||
function parenthesised() {
|
function parenthesised() {
|
||||||
expect("(");
|
expect("(");
|
||||||
var exp = expression(true);
|
var exp = expression();
|
||||||
expect(")");
|
expect(")");
|
||||||
return exp;
|
return exp;
|
||||||
}
|
}
|
||||||
@@ -758,7 +770,7 @@ function parse($TEXT, options) {
|
|||||||
switch (S.token.type) {
|
switch (S.token.type) {
|
||||||
case "string":
|
case "string":
|
||||||
var dir = S.in_directives;
|
var dir = S.in_directives;
|
||||||
var body = expression(true);
|
var body = expression();
|
||||||
if (dir) {
|
if (dir) {
|
||||||
if (body instanceof AST_String) {
|
if (body instanceof AST_String) {
|
||||||
var value = body.start.raw.slice(1, -1);
|
var value = body.start.raw.slice(1, -1);
|
||||||
@@ -771,12 +783,25 @@ function parse($TEXT, options) {
|
|||||||
semicolon();
|
semicolon();
|
||||||
return dir ? new AST_Directive(body) : new AST_SimpleStatement({ body: body });
|
return dir ? new AST_Directive(body) : new AST_SimpleStatement({ body: body });
|
||||||
case "num":
|
case "num":
|
||||||
|
case "bigint":
|
||||||
case "regexp":
|
case "regexp":
|
||||||
case "operator":
|
case "operator":
|
||||||
case "atom":
|
case "atom":
|
||||||
return simple_statement();
|
return simple_statement();
|
||||||
|
|
||||||
case "name":
|
case "name":
|
||||||
|
switch (S.token.value) {
|
||||||
|
case "async":
|
||||||
|
if (is_token(peek(), "keyword", "function")) {
|
||||||
|
next();
|
||||||
|
next();
|
||||||
|
return function_(AST_AsyncDefun);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "await":
|
||||||
|
if (S.in_async) return simple_statement();
|
||||||
|
break;
|
||||||
|
}
|
||||||
return is_token(peek(), "punc", ":")
|
return is_token(peek(), "punc", ":")
|
||||||
? labeled_statement()
|
? labeled_statement()
|
||||||
: simple_statement();
|
: simple_statement();
|
||||||
@@ -865,7 +890,7 @@ function parse($TEXT, options) {
|
|||||||
if (is("punc", ";")) {
|
if (is("punc", ";")) {
|
||||||
next();
|
next();
|
||||||
} else if (!can_insert_semicolon()) {
|
} else if (!can_insert_semicolon()) {
|
||||||
value = expression(true);
|
value = expression();
|
||||||
semicolon();
|
semicolon();
|
||||||
}
|
}
|
||||||
return new AST_Return({
|
return new AST_Return({
|
||||||
@@ -883,7 +908,7 @@ function parse($TEXT, options) {
|
|||||||
next();
|
next();
|
||||||
if (has_newline_before(S.token))
|
if (has_newline_before(S.token))
|
||||||
croak("Illegal newline after 'throw'");
|
croak("Illegal newline after 'throw'");
|
||||||
var value = expression(true);
|
var value = expression();
|
||||||
semicolon();
|
semicolon();
|
||||||
return new AST_Throw({
|
return new AST_Throw({
|
||||||
value: value
|
value: value
|
||||||
@@ -934,9 +959,7 @@ function parse($TEXT, options) {
|
|||||||
// https://github.com/mishoo/UglifyJS/issues/287
|
// https://github.com/mishoo/UglifyJS/issues/287
|
||||||
label.references.forEach(function(ref) {
|
label.references.forEach(function(ref) {
|
||||||
if (ref instanceof AST_Continue) {
|
if (ref instanceof AST_Continue) {
|
||||||
ref = ref.label.start;
|
token_error(ref.label.start, "Continue label `" + label.name + "` must refer to IterationStatement");
|
||||||
croak("Continue label `" + label.name + "` refers to non-IterationStatement.",
|
|
||||||
ref.line, ref.col, ref.pos);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -944,7 +967,7 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function simple_statement() {
|
function simple_statement() {
|
||||||
var body = expression(true);
|
var body = expression();
|
||||||
semicolon();
|
semicolon();
|
||||||
return new AST_SimpleStatement({ body: body });
|
return new AST_SimpleStatement({ body: body });
|
||||||
}
|
}
|
||||||
@@ -958,7 +981,7 @@ function parse($TEXT, options) {
|
|||||||
ldef = find_if(function(l) {
|
ldef = find_if(function(l) {
|
||||||
return l.name == label.name;
|
return l.name == label.name;
|
||||||
}, S.labels);
|
}, S.labels);
|
||||||
if (!ldef) croak("Undefined label " + label.name);
|
if (!ldef) token_error(label.start, "Undefined label " + label.name);
|
||||||
label.thedef = ldef;
|
label.thedef = ldef;
|
||||||
} else if (S.in_loop == 0) croak(type.TYPE + " not inside a loop or switch");
|
} else if (S.in_loop == 0) croak(type.TYPE + " not inside a loop or switch");
|
||||||
semicolon();
|
semicolon();
|
||||||
@@ -977,13 +1000,14 @@ function parse($TEXT, options) {
|
|||||||
? (next(), let_(true))
|
? (next(), let_(true))
|
||||||
: is("keyword", "var")
|
: is("keyword", "var")
|
||||||
? (next(), var_(true))
|
? (next(), var_(true))
|
||||||
: expression(true, true);
|
: expression(true);
|
||||||
if (is("operator", "in")) {
|
if (is("operator", "in")) {
|
||||||
if (init instanceof AST_Definitions) {
|
if (init instanceof AST_Definitions) {
|
||||||
if (init.definitions.length > 1)
|
if (init.definitions.length > 1) {
|
||||||
croak("Only one variable declaration allowed in for..in loop", init.start.line, init.start.col, init.start.pos);
|
token_error(init.start, "Only one variable declaration allowed in for..in loop");
|
||||||
|
}
|
||||||
} else if (!(is_assignable(init) || (init = to_destructured(init)) instanceof AST_Destructured)) {
|
} else if (!(is_assignable(init) || (init = to_destructured(init)) instanceof AST_Destructured)) {
|
||||||
croak("Invalid left-hand side in for..in loop", init.start.line, init.start.col, init.start.pos);
|
token_error(init.start, "Invalid left-hand side in for..in loop");
|
||||||
}
|
}
|
||||||
next();
|
next();
|
||||||
return for_in(init);
|
return for_in(init);
|
||||||
@@ -994,9 +1018,9 @@ function parse($TEXT, options) {
|
|||||||
|
|
||||||
function regular_for(init) {
|
function regular_for(init) {
|
||||||
expect(";");
|
expect(";");
|
||||||
var test = is("punc", ";") ? null : expression(true);
|
var test = is("punc", ";") ? null : expression();
|
||||||
expect(";");
|
expect(";");
|
||||||
var step = is("punc", ")") ? null : expression(true);
|
var step = is("punc", ")") ? null : expression();
|
||||||
expect(")");
|
expect(")");
|
||||||
return new AST_For({
|
return new AST_For({
|
||||||
init : init,
|
init : init,
|
||||||
@@ -1007,7 +1031,7 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function for_in(init) {
|
function for_in(init) {
|
||||||
var obj = expression(true);
|
var obj = expression();
|
||||||
expect(")");
|
expect(")");
|
||||||
return new AST_ForIn({
|
return new AST_ForIn({
|
||||||
init : init,
|
init : init,
|
||||||
@@ -1016,20 +1040,132 @@ function parse($TEXT, options) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function to_funarg(node) {
|
||||||
|
if (node instanceof AST_Array) {
|
||||||
|
var rest = null;
|
||||||
|
if (node.elements[node.elements.length - 1] instanceof AST_Spread) {
|
||||||
|
rest = to_funarg(node.elements.pop().expression);
|
||||||
|
}
|
||||||
|
return new AST_DestructuredArray({
|
||||||
|
start: node.start,
|
||||||
|
elements: node.elements.map(to_funarg),
|
||||||
|
rest: rest,
|
||||||
|
end: node.end,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (node instanceof AST_Assign) return new AST_DefaultValue({
|
||||||
|
start: node.start,
|
||||||
|
name: to_funarg(node.left),
|
||||||
|
value: node.right,
|
||||||
|
end: node.end,
|
||||||
|
});
|
||||||
|
if (node instanceof AST_DefaultValue) {
|
||||||
|
node.name = to_funarg(node.name);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
if (node instanceof AST_DestructuredArray) {
|
||||||
|
node.elements = node.elements.map(to_funarg);
|
||||||
|
if (node.rest) node.rest = to_funarg(node.rest);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
if (node instanceof AST_DestructuredObject) {
|
||||||
|
node.properties.forEach(function(prop) {
|
||||||
|
prop.value = to_funarg(prop.value);
|
||||||
|
});
|
||||||
|
if (node.rest) node.rest = to_funarg(node.rest);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
if (node instanceof AST_Hole) return node;
|
||||||
|
if (node instanceof AST_Object) {
|
||||||
|
var rest = null;
|
||||||
|
if (node.properties[node.properties.length - 1] instanceof AST_Spread) {
|
||||||
|
rest = to_funarg(node.properties.pop().expression);
|
||||||
|
}
|
||||||
|
return new AST_DestructuredObject({
|
||||||
|
start: node.start,
|
||||||
|
properties: node.properties.map(function(prop) {
|
||||||
|
if (!(prop instanceof AST_ObjectKeyVal)) token_error(prop.start, "Invalid destructuring assignment");
|
||||||
|
return new AST_DestructuredKeyVal({
|
||||||
|
start: prop.start,
|
||||||
|
key: prop.key,
|
||||||
|
value: to_funarg(prop.value),
|
||||||
|
end: prop.end,
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
rest: rest,
|
||||||
|
end: node.end,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (node instanceof AST_SymbolFunarg) return node;
|
||||||
|
if (node instanceof AST_SymbolRef) return new AST_SymbolFunarg(node);
|
||||||
|
token_error(node.start, "Invalid arrow parameter");
|
||||||
|
}
|
||||||
|
|
||||||
|
function arrow(exprs, start, async) {
|
||||||
|
var was_async = S.in_async;
|
||||||
|
S.in_async = async;
|
||||||
|
var was_funarg = S.in_funarg;
|
||||||
|
S.in_funarg = S.in_function;
|
||||||
|
var argnames = exprs.map(to_funarg);
|
||||||
|
var rest = exprs.rest || null;
|
||||||
|
if (rest) rest = to_funarg(rest);
|
||||||
|
S.in_funarg = was_funarg;
|
||||||
|
expect("=>");
|
||||||
|
var body, value;
|
||||||
|
var loop = S.in_loop;
|
||||||
|
var labels = S.labels;
|
||||||
|
++S.in_function;
|
||||||
|
S.in_directives = true;
|
||||||
|
S.input.push_directives_stack();
|
||||||
|
S.in_loop = 0;
|
||||||
|
S.labels = [];
|
||||||
|
if (is("punc", "{")) {
|
||||||
|
body = block_();
|
||||||
|
value = null;
|
||||||
|
if (S.input.has_directive("use strict")) {
|
||||||
|
argnames.forEach(strict_verify_symbol);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
body = [];
|
||||||
|
value = maybe_assign();
|
||||||
|
}
|
||||||
|
S.input.pop_directives_stack();
|
||||||
|
--S.in_function;
|
||||||
|
S.in_loop = loop;
|
||||||
|
S.labels = labels;
|
||||||
|
S.in_async = was_async;
|
||||||
|
return new (async ? AST_AsyncArrow : AST_Arrow)({
|
||||||
|
start: start,
|
||||||
|
argnames: argnames,
|
||||||
|
rest: rest,
|
||||||
|
body: body,
|
||||||
|
value: value,
|
||||||
|
end: prev(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
var function_ = function(ctor) {
|
var function_ = function(ctor) {
|
||||||
var in_statement = ctor === AST_Defun;
|
var was_async = S.in_async;
|
||||||
var name = is("name") ? as_symbol(in_statement ? AST_SymbolDefun : AST_SymbolLambda) : null;
|
var name;
|
||||||
if (in_statement && !name)
|
if (ctor === AST_AsyncDefun) {
|
||||||
expect_token("name");
|
name = as_symbol(AST_SymbolDefun);
|
||||||
|
S.in_async = true;
|
||||||
|
} else if (ctor === AST_Defun) {
|
||||||
|
name = as_symbol(AST_SymbolDefun);
|
||||||
|
S.in_async = false;
|
||||||
|
} else {
|
||||||
|
S.in_async = ctor === AST_AsyncFunction;
|
||||||
|
name = as_symbol(AST_SymbolLambda, true);
|
||||||
|
}
|
||||||
if (name && ctor !== AST_Accessor && !(name instanceof AST_SymbolDeclaration))
|
if (name && ctor !== AST_Accessor && !(name instanceof AST_SymbolDeclaration))
|
||||||
unexpected(prev());
|
unexpected(prev());
|
||||||
expect("(");
|
expect("(");
|
||||||
var argnames = [];
|
var was_funarg = S.in_funarg;
|
||||||
for (var first = true; !is("punc", ")");) {
|
S.in_funarg = S.in_function;
|
||||||
if (first) first = false; else expect(",");
|
var argnames = expr_list(")", !options.strict, false, function() {
|
||||||
argnames.push(maybe_destructured(AST_SymbolFunarg));
|
return maybe_default(AST_SymbolFunarg);
|
||||||
}
|
});
|
||||||
next();
|
S.in_funarg = was_funarg;
|
||||||
var loop = S.in_loop;
|
var loop = S.in_loop;
|
||||||
var labels = S.labels;
|
var labels = S.labels;
|
||||||
++S.in_function;
|
++S.in_function;
|
||||||
@@ -1041,14 +1177,17 @@ function parse($TEXT, options) {
|
|||||||
if (S.input.has_directive("use strict")) {
|
if (S.input.has_directive("use strict")) {
|
||||||
if (name) strict_verify_symbol(name);
|
if (name) strict_verify_symbol(name);
|
||||||
argnames.forEach(strict_verify_symbol);
|
argnames.forEach(strict_verify_symbol);
|
||||||
|
if (argnames.rest) strict_verify_symbol(argnames.rest);
|
||||||
}
|
}
|
||||||
S.input.pop_directives_stack();
|
S.input.pop_directives_stack();
|
||||||
--S.in_function;
|
--S.in_function;
|
||||||
S.in_loop = loop;
|
S.in_loop = loop;
|
||||||
S.labels = labels;
|
S.labels = labels;
|
||||||
|
S.in_async = was_async;
|
||||||
return new ctor({
|
return new ctor({
|
||||||
name: name,
|
name: name,
|
||||||
argnames: argnames,
|
argnames: argnames,
|
||||||
|
rest: argnames.rest || null,
|
||||||
body: body
|
body: body
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -1070,7 +1209,7 @@ function parse($TEXT, options) {
|
|||||||
expect("{");
|
expect("{");
|
||||||
var a = [];
|
var a = [];
|
||||||
while (!is("punc", "}")) {
|
while (!is("punc", "}")) {
|
||||||
if (is("eof")) expect_token("punc", "}");
|
if (is("eof")) expect("}");
|
||||||
a.push(statement());
|
a.push(statement());
|
||||||
}
|
}
|
||||||
next();
|
next();
|
||||||
@@ -1081,13 +1220,13 @@ function parse($TEXT, options) {
|
|||||||
expect("{");
|
expect("{");
|
||||||
var a = [], branch, cur, default_branch, tmp;
|
var a = [], branch, cur, default_branch, tmp;
|
||||||
while (!is("punc", "}")) {
|
while (!is("punc", "}")) {
|
||||||
if (is("eof")) expect_token("punc", "}");
|
if (is("eof")) expect("}");
|
||||||
if (is("keyword", "case")) {
|
if (is("keyword", "case")) {
|
||||||
if (branch) branch.end = prev();
|
if (branch) branch.end = prev();
|
||||||
cur = [];
|
cur = [];
|
||||||
branch = new AST_Case({
|
branch = new AST_Case({
|
||||||
start : (tmp = S.token, next(), tmp),
|
start : (tmp = S.token, next(), tmp),
|
||||||
expression : expression(true),
|
expression : expression(),
|
||||||
body : cur
|
body : cur
|
||||||
});
|
});
|
||||||
a.push(branch);
|
a.push(branch);
|
||||||
@@ -1120,7 +1259,7 @@ function parse($TEXT, options) {
|
|||||||
var name = null;
|
var name = null;
|
||||||
if (is("punc", "(")) {
|
if (is("punc", "(")) {
|
||||||
next();
|
next();
|
||||||
name = as_symbol(AST_SymbolCatch);
|
name = maybe_destructured(AST_SymbolCatch);
|
||||||
expect(")");
|
expect(")");
|
||||||
}
|
}
|
||||||
bcatch = new AST_Catch({
|
bcatch = new AST_Catch({
|
||||||
@@ -1156,7 +1295,7 @@ function parse($TEXT, options) {
|
|||||||
var value = null;
|
var value = null;
|
||||||
if (is("operator", "=")) {
|
if (is("operator", "=")) {
|
||||||
next();
|
next();
|
||||||
value = expression(false, no_in);
|
value = maybe_assign(no_in);
|
||||||
} else if (!no_in && (type === AST_SymbolConst || name instanceof AST_Destructured)) {
|
} else if (!no_in && (type === AST_SymbolConst || name instanceof AST_Destructured)) {
|
||||||
croak("Missing initializer in declaration");
|
croak("Missing initializer in declaration");
|
||||||
}
|
}
|
||||||
@@ -1203,7 +1342,7 @@ function parse($TEXT, options) {
|
|||||||
var newexp = expr_atom(false), args;
|
var newexp = expr_atom(false), args;
|
||||||
if (is("punc", "(")) {
|
if (is("punc", "(")) {
|
||||||
next();
|
next();
|
||||||
args = expr_list(")");
|
args = expr_list(")", !options.strict);
|
||||||
} else {
|
} else {
|
||||||
args = [];
|
args = [];
|
||||||
}
|
}
|
||||||
@@ -1220,12 +1359,12 @@ function parse($TEXT, options) {
|
|||||||
function as_atom_node() {
|
function as_atom_node() {
|
||||||
var tok = S.token, ret;
|
var tok = S.token, ret;
|
||||||
switch (tok.type) {
|
switch (tok.type) {
|
||||||
case "name":
|
|
||||||
ret = _make_symbol(AST_SymbolRef, tok);
|
|
||||||
break;
|
|
||||||
case "num":
|
case "num":
|
||||||
ret = new AST_Number({ start: tok, end: tok, value: tok.value });
|
ret = new AST_Number({ start: tok, end: tok, value: tok.value });
|
||||||
break;
|
break;
|
||||||
|
case "bigint":
|
||||||
|
ret = new AST_BigInt({ start: tok, end: tok, value: tok.value });
|
||||||
|
break;
|
||||||
case "string":
|
case "string":
|
||||||
ret = new AST_String({
|
ret = new AST_String({
|
||||||
start : tok,
|
start : tok,
|
||||||
@@ -1264,7 +1403,11 @@ function parse($TEXT, options) {
|
|||||||
switch (start.value) {
|
switch (start.value) {
|
||||||
case "(":
|
case "(":
|
||||||
next();
|
next();
|
||||||
var ex = expression(true);
|
if (is("punc", ")")) {
|
||||||
|
next();
|
||||||
|
return arrow([], start);
|
||||||
|
}
|
||||||
|
var ex = expression(false, true);
|
||||||
var len = start.comments_before.length;
|
var len = start.comments_before.length;
|
||||||
[].unshift.apply(ex.start.comments_before, start.comments_before);
|
[].unshift.apply(ex.start.comments_before, start.comments_before);
|
||||||
start.comments_before.length = 0;
|
start.comments_before.length = 0;
|
||||||
@@ -1287,6 +1430,7 @@ function parse($TEXT, options) {
|
|||||||
end.comments_after = ex.end.comments_after;
|
end.comments_after = ex.end.comments_after;
|
||||||
ex.end = end;
|
ex.end = end;
|
||||||
if (ex instanceof AST_Call) mark_pure(ex);
|
if (ex instanceof AST_Call) mark_pure(ex);
|
||||||
|
if (is("punc", "=>")) return arrow(ex instanceof AST_Sequence ? ex.expressions : [ ex ], start);
|
||||||
return subscripts(ex, allow_calls);
|
return subscripts(ex, allow_calls);
|
||||||
case "[":
|
case "[":
|
||||||
return subscripts(array_(), allow_calls);
|
return subscripts(array_(), allow_calls);
|
||||||
@@ -1302,6 +1446,35 @@ function parse($TEXT, options) {
|
|||||||
func.end = prev();
|
func.end = prev();
|
||||||
return subscripts(func, allow_calls);
|
return subscripts(func, allow_calls);
|
||||||
}
|
}
|
||||||
|
if (is("name")) {
|
||||||
|
var sym = _make_symbol(AST_SymbolRef, start);
|
||||||
|
next();
|
||||||
|
if (sym.name == "async") {
|
||||||
|
if (is("keyword", "function")) {
|
||||||
|
next();
|
||||||
|
var func = function_(AST_AsyncFunction);
|
||||||
|
func.start = start;
|
||||||
|
func.end = prev();
|
||||||
|
return subscripts(func, allow_calls);
|
||||||
|
}
|
||||||
|
if (is("name")) {
|
||||||
|
start = S.token;
|
||||||
|
sym = _make_symbol(AST_SymbolRef, start);
|
||||||
|
next();
|
||||||
|
return arrow([ sym ], start, true);
|
||||||
|
}
|
||||||
|
if (is("punc", "(")) {
|
||||||
|
var call = subscripts(sym, allow_calls);
|
||||||
|
if (!is("punc", "=>")) return call;
|
||||||
|
var args = call.args;
|
||||||
|
if (args[args.length - 1] instanceof AST_Spread) {
|
||||||
|
args.rest = args.pop().expression;
|
||||||
|
}
|
||||||
|
return arrow(args, start, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return is("punc", "=>") ? arrow([ sym ], start) : subscripts(sym, allow_calls);
|
||||||
|
}
|
||||||
if (ATOMIC_START_TOKEN[S.token.type]) {
|
if (ATOMIC_START_TOKEN[S.token.type]) {
|
||||||
return subscripts(as_atom_node(), allow_calls);
|
return subscripts(as_atom_node(), allow_calls);
|
||||||
}
|
}
|
||||||
@@ -1309,18 +1482,29 @@ function parse($TEXT, options) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function expr_list(closing, allow_trailing_comma, allow_empty, parser) {
|
function expr_list(closing, allow_trailing_comma, allow_empty, parser) {
|
||||||
if (!parser) parser = expression;
|
if (!parser) parser = maybe_assign;
|
||||||
var first = true, a = [];
|
var first = true, a = [];
|
||||||
while (!is("punc", closing)) {
|
while (!is("punc", closing)) {
|
||||||
if (first) first = false; else expect(",");
|
if (first) first = false; else expect(",");
|
||||||
if (allow_trailing_comma && is("punc", closing)) break;
|
if (allow_trailing_comma && is("punc", closing)) break;
|
||||||
if (is("punc", ",") && allow_empty) {
|
if (allow_empty && is("punc", ",")) {
|
||||||
a.push(new AST_Hole({ start: S.token, end: S.token }));
|
a.push(new AST_Hole({ start: S.token, end: S.token }));
|
||||||
} else {
|
} else if (!is("operator", "...")) {
|
||||||
a.push(parser());
|
a.push(parser());
|
||||||
|
} else if (parser === maybe_assign) {
|
||||||
|
a.push(new AST_Spread({
|
||||||
|
start: S.token,
|
||||||
|
expression: (next(), parser()),
|
||||||
|
end: prev(),
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
next();
|
||||||
|
a.rest = parser();
|
||||||
|
if (a.rest instanceof AST_DefaultValue) token_error(a.rest.start, "Invalid rest parameter");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
next();
|
expect(closing);
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1343,6 +1527,41 @@ function parse($TEXT, options) {
|
|||||||
// allow trailing comma
|
// allow trailing comma
|
||||||
if (!options.strict && is("punc", "}")) break;
|
if (!options.strict && is("punc", "}")) break;
|
||||||
var start = S.token;
|
var start = S.token;
|
||||||
|
if (is("operator", "...")) {
|
||||||
|
next();
|
||||||
|
a.push(new AST_Spread({
|
||||||
|
start: start,
|
||||||
|
expression: maybe_assign(),
|
||||||
|
end: prev(),
|
||||||
|
}));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (is_token(peek(), "operator", "=")) {
|
||||||
|
var name = as_symbol(AST_SymbolRef);
|
||||||
|
next();
|
||||||
|
a.push(new AST_ObjectKeyVal({
|
||||||
|
start: start,
|
||||||
|
key: start.value,
|
||||||
|
value: new AST_Assign({
|
||||||
|
start: start,
|
||||||
|
left: name,
|
||||||
|
operator: "=",
|
||||||
|
right: maybe_assign(),
|
||||||
|
end: prev(),
|
||||||
|
}),
|
||||||
|
end: prev(),
|
||||||
|
}));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (is_token(peek(), "punc", ",") || is_token(peek(), "punc", "}")) {
|
||||||
|
a.push(new AST_ObjectKeyVal({
|
||||||
|
start: start,
|
||||||
|
key: start.value,
|
||||||
|
value: as_symbol(AST_SymbolRef),
|
||||||
|
end: prev(),
|
||||||
|
}));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
var key = as_property_key();
|
var key = as_property_key();
|
||||||
if (is("punc", "(")) {
|
if (is("punc", "(")) {
|
||||||
var func_start = S.token;
|
var func_start = S.token;
|
||||||
@@ -1357,7 +1576,30 @@ function parse($TEXT, options) {
|
|||||||
}));
|
}));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!is("punc", ":") && start.type == "name") switch (key) {
|
if (is("punc", ":")) {
|
||||||
|
next();
|
||||||
|
a.push(new AST_ObjectKeyVal({
|
||||||
|
start: start,
|
||||||
|
key: key,
|
||||||
|
value: maybe_assign(),
|
||||||
|
end: prev(),
|
||||||
|
}));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (start.type == "name") switch (key) {
|
||||||
|
case "async":
|
||||||
|
key = as_property_key();
|
||||||
|
var func_start = S.token;
|
||||||
|
var func = function_(AST_AsyncFunction);
|
||||||
|
func.start = func_start;
|
||||||
|
func.end = prev();
|
||||||
|
a.push(new AST_ObjectKeyVal({
|
||||||
|
start: start,
|
||||||
|
key: key,
|
||||||
|
value: func,
|
||||||
|
end: prev(),
|
||||||
|
}));
|
||||||
|
continue;
|
||||||
case "get":
|
case "get":
|
||||||
a.push(new AST_ObjectGetter({
|
a.push(new AST_ObjectGetter({
|
||||||
start: start,
|
start: start,
|
||||||
@@ -1374,22 +1616,8 @@ function parse($TEXT, options) {
|
|||||||
end: prev(),
|
end: prev(),
|
||||||
}));
|
}));
|
||||||
continue;
|
continue;
|
||||||
default:
|
|
||||||
a.push(new AST_ObjectKeyVal({
|
|
||||||
start: start,
|
|
||||||
key: key,
|
|
||||||
value: _make_symbol(AST_SymbolRef, start),
|
|
||||||
end: prev(),
|
|
||||||
}));
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
expect(":");
|
unexpected();
|
||||||
a.push(new AST_ObjectKeyVal({
|
|
||||||
start: start,
|
|
||||||
key: key,
|
|
||||||
value: expression(false),
|
|
||||||
end: prev(),
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
next();
|
next();
|
||||||
return new AST_Object({ properties: a });
|
return new AST_Object({ properties: a });
|
||||||
@@ -1408,9 +1636,8 @@ function parse($TEXT, options) {
|
|||||||
next();
|
next();
|
||||||
return "" + tmp.value;
|
return "" + tmp.value;
|
||||||
case "punc":
|
case "punc":
|
||||||
if (tmp.value != "[") unexpected();
|
expect("[");
|
||||||
next();
|
var key = maybe_assign();
|
||||||
var key = expression(false);
|
|
||||||
expect("]");
|
expect("]");
|
||||||
return key;
|
return key;
|
||||||
default:
|
default:
|
||||||
@@ -1419,14 +1646,14 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function as_name() {
|
function as_name() {
|
||||||
if (!is("name")) expect_token("name");
|
|
||||||
var name = S.token.value;
|
var name = S.token.value;
|
||||||
next();
|
expect_token("name");
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _make_symbol(type, token) {
|
function _make_symbol(type, token) {
|
||||||
var name = token.value;
|
var name = token.value;
|
||||||
|
if (name === "await" && S.in_async) unexpected(token);
|
||||||
return new (name === "this" ? AST_This : type)({
|
return new (name === "this" ? AST_This : type)({
|
||||||
name: "" + name,
|
name: "" + name,
|
||||||
start: token,
|
start: token,
|
||||||
@@ -1436,7 +1663,7 @@ function parse($TEXT, options) {
|
|||||||
|
|
||||||
function strict_verify_symbol(sym) {
|
function strict_verify_symbol(sym) {
|
||||||
if (sym.name == "arguments" || sym.name == "eval")
|
if (sym.name == "arguments" || sym.name == "eval")
|
||||||
croak("Unexpected " + sym.name + " in strict mode", sym.start.line, sym.start.col, sym.start.pos);
|
token_error(sym.start, "Unexpected " + sym.name + " in strict mode");
|
||||||
}
|
}
|
||||||
|
|
||||||
function as_symbol(type, noerror) {
|
function as_symbol(type, noerror) {
|
||||||
@@ -1456,50 +1683,81 @@ function parse($TEXT, options) {
|
|||||||
var start = S.token;
|
var start = S.token;
|
||||||
if (is("punc", "[")) {
|
if (is("punc", "[")) {
|
||||||
next();
|
next();
|
||||||
|
var elements = expr_list("]", !options.strict, true, function() {
|
||||||
|
return maybe_default(type);
|
||||||
|
});
|
||||||
return new AST_DestructuredArray({
|
return new AST_DestructuredArray({
|
||||||
start: start,
|
start: start,
|
||||||
elements: expr_list("]", !options.strict, true, function() {
|
elements: elements,
|
||||||
return maybe_destructured(type);
|
rest: elements.rest || null,
|
||||||
}),
|
|
||||||
end: prev(),
|
end: prev(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (is("punc", "{")) {
|
if (is("punc", "{")) {
|
||||||
next();
|
next();
|
||||||
var first = true, a = [];
|
var first = true, a = [], rest = null;
|
||||||
while (!is("punc", "}")) {
|
while (!is("punc", "}")) {
|
||||||
if (first) first = false; else expect(",");
|
if (first) first = false; else expect(",");
|
||||||
// allow trailing comma
|
// allow trailing comma
|
||||||
if (!options.strict && is("punc", "}")) break;
|
if (!options.strict && is("punc", "}")) break;
|
||||||
var key_start = S.token;
|
var key_start = S.token;
|
||||||
var key = as_property_key();
|
if (is("punc", "[") || is_token(peek(), "punc", ":")) {
|
||||||
if (!is("punc", ":") && key_start.type == "name") {
|
var key = as_property_key();
|
||||||
|
expect(":");
|
||||||
a.push(new AST_DestructuredKeyVal({
|
a.push(new AST_DestructuredKeyVal({
|
||||||
start: key_start,
|
start: key_start,
|
||||||
key: key,
|
key: key,
|
||||||
value: _make_symbol(type, key_start),
|
value: maybe_default(type),
|
||||||
end: prev(),
|
end: prev(),
|
||||||
}));
|
}));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
expect(":");
|
if (is("operator", "...")) {
|
||||||
|
next();
|
||||||
|
rest = maybe_destructured(type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
var name = as_symbol(type);
|
||||||
|
if (is("operator", "=")) {
|
||||||
|
next();
|
||||||
|
name = new AST_DefaultValue({
|
||||||
|
start: name.start,
|
||||||
|
name: name,
|
||||||
|
value: maybe_assign(),
|
||||||
|
end: prev(),
|
||||||
|
});
|
||||||
|
}
|
||||||
a.push(new AST_DestructuredKeyVal({
|
a.push(new AST_DestructuredKeyVal({
|
||||||
start: key_start,
|
start: key_start,
|
||||||
key: key,
|
key: key_start.value,
|
||||||
value: maybe_destructured(type),
|
value: name,
|
||||||
end: prev(),
|
end: prev(),
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
next();
|
expect("}");
|
||||||
return new AST_DestructuredObject({
|
return new AST_DestructuredObject({
|
||||||
start: start,
|
start: start,
|
||||||
properties: a,
|
properties: a,
|
||||||
|
rest: rest,
|
||||||
end: prev(),
|
end: prev(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return as_symbol(type);
|
return as_symbol(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function maybe_default(type) {
|
||||||
|
var start = S.token;
|
||||||
|
var name = maybe_destructured(type);
|
||||||
|
if (!is("operator", "=")) return name;
|
||||||
|
next();
|
||||||
|
return new AST_DefaultValue({
|
||||||
|
start: start,
|
||||||
|
name: name,
|
||||||
|
value: maybe_assign(),
|
||||||
|
end: prev(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function mark_pure(call) {
|
function mark_pure(call) {
|
||||||
var start = call.start;
|
var start = call.start;
|
||||||
var comments = start.comments_before;
|
var comments = start.comments_before;
|
||||||
@@ -1526,7 +1784,7 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
if (is("punc", "[")) {
|
if (is("punc", "[")) {
|
||||||
next();
|
next();
|
||||||
var prop = expression(true);
|
var prop = expression();
|
||||||
expect("]");
|
expect("]");
|
||||||
return subscripts(new AST_Sub({
|
return subscripts(new AST_Sub({
|
||||||
start : start,
|
start : start,
|
||||||
@@ -1540,7 +1798,7 @@ function parse($TEXT, options) {
|
|||||||
var call = new AST_Call({
|
var call = new AST_Call({
|
||||||
start : start,
|
start : start,
|
||||||
expression : expr,
|
expression : expr,
|
||||||
args : expr_list(")"),
|
args : expr_list(")", !options.strict),
|
||||||
end : prev()
|
end : prev()
|
||||||
});
|
});
|
||||||
mark_pure(call);
|
mark_pure(call);
|
||||||
@@ -1549,17 +1807,17 @@ function parse($TEXT, options) {
|
|||||||
return expr;
|
return expr;
|
||||||
};
|
};
|
||||||
|
|
||||||
var maybe_unary = function(allow_calls) {
|
function maybe_unary() {
|
||||||
var start = S.token;
|
var start = S.token;
|
||||||
if (is("operator") && UNARY_PREFIX[start.value]) {
|
if (is("operator") && UNARY_PREFIX[start.value]) {
|
||||||
next();
|
next();
|
||||||
handle_regexp();
|
handle_regexp();
|
||||||
var ex = make_unary(AST_UnaryPrefix, start, maybe_unary(allow_calls));
|
var ex = make_unary(AST_UnaryPrefix, start, maybe_await());
|
||||||
ex.start = start;
|
ex.start = start;
|
||||||
ex.end = prev();
|
ex.end = prev();
|
||||||
return ex;
|
return ex;
|
||||||
}
|
}
|
||||||
var val = expr_atom(allow_calls);
|
var val = expr_atom(true);
|
||||||
while (is("operator") && UNARY_POSTFIX[S.token.value] && !has_newline_before(S.token)) {
|
while (is("operator") && UNARY_POSTFIX[S.token.value] && !has_newline_before(S.token)) {
|
||||||
val = make_unary(AST_UnaryPostfix, S.token, val);
|
val = make_unary(AST_UnaryPostfix, S.token, val);
|
||||||
val.start = start;
|
val.start = start;
|
||||||
@@ -1567,7 +1825,7 @@ function parse($TEXT, options) {
|
|||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
return val;
|
return val;
|
||||||
};
|
}
|
||||||
|
|
||||||
function make_unary(ctor, token, expr) {
|
function make_unary(ctor, token, expr) {
|
||||||
var op = token.value;
|
var op = token.value;
|
||||||
@@ -1575,23 +1833,36 @@ function parse($TEXT, options) {
|
|||||||
case "++":
|
case "++":
|
||||||
case "--":
|
case "--":
|
||||||
if (!is_assignable(expr))
|
if (!is_assignable(expr))
|
||||||
croak("Invalid use of " + op + " operator", token.line, token.col, token.pos);
|
token_error(token, "Invalid use of " + op + " operator");
|
||||||
break;
|
break;
|
||||||
case "delete":
|
case "delete":
|
||||||
if (expr instanceof AST_SymbolRef && S.input.has_directive("use strict"))
|
if (expr instanceof AST_SymbolRef && S.input.has_directive("use strict"))
|
||||||
croak("Calling delete on expression not allowed in strict mode", expr.start.line, expr.start.col, expr.start.pos);
|
token_error(expr.start, "Calling delete on expression not allowed in strict mode");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return new ctor({ operator: op, expression: expr });
|
return new ctor({ operator: op, expression: expr });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function maybe_await() {
|
||||||
|
var start = S.token;
|
||||||
|
if (!(S.in_async && is("name", "await"))) return maybe_unary();
|
||||||
|
if (S.in_funarg === S.in_function) croak("Invalid use of await in function argument");
|
||||||
|
S.input.context().regex_allowed = true;
|
||||||
|
next();
|
||||||
|
return new AST_Await({
|
||||||
|
start: start,
|
||||||
|
expression: maybe_await(),
|
||||||
|
end: prev(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
var expr_op = function(left, min_prec, no_in) {
|
var expr_op = function(left, min_prec, no_in) {
|
||||||
var op = is("operator") ? S.token.value : null;
|
var op = is("operator") ? S.token.value : null;
|
||||||
if (op == "in" && no_in) op = null;
|
if (op == "in" && no_in) op = null;
|
||||||
var prec = op != null ? PRECEDENCE[op] : null;
|
var prec = op != null ? PRECEDENCE[op] : null;
|
||||||
if (prec != null && prec > min_prec) {
|
if (prec != null && prec > min_prec) {
|
||||||
next();
|
next();
|
||||||
var right = expr_op(maybe_unary(true), prec, no_in);
|
var right = expr_op(maybe_await(), op == "**" ? prec - 1 : prec, no_in);
|
||||||
return expr_op(new AST_Binary({
|
return expr_op(new AST_Binary({
|
||||||
start : left.start,
|
start : left.start,
|
||||||
left : left,
|
left : left,
|
||||||
@@ -1604,7 +1875,7 @@ function parse($TEXT, options) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function expr_ops(no_in) {
|
function expr_ops(no_in) {
|
||||||
return expr_op(maybe_unary(true), 0, no_in);
|
return expr_op(maybe_await(), 0, no_in);
|
||||||
}
|
}
|
||||||
|
|
||||||
var maybe_conditional = function(no_in) {
|
var maybe_conditional = function(no_in) {
|
||||||
@@ -1612,13 +1883,13 @@ function parse($TEXT, options) {
|
|||||||
var expr = expr_ops(no_in);
|
var expr = expr_ops(no_in);
|
||||||
if (is("operator", "?")) {
|
if (is("operator", "?")) {
|
||||||
next();
|
next();
|
||||||
var yes = expression(false);
|
var yes = maybe_assign();
|
||||||
expect(":");
|
expect(":");
|
||||||
return new AST_Conditional({
|
return new AST_Conditional({
|
||||||
start : start,
|
start : start,
|
||||||
condition : expr,
|
condition : expr,
|
||||||
consequent : yes,
|
consequent : yes,
|
||||||
alternative : expression(false, no_in),
|
alternative : maybe_assign(no_in),
|
||||||
end : prev()
|
end : prev()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1631,22 +1902,47 @@ function parse($TEXT, options) {
|
|||||||
|
|
||||||
function to_destructured(node) {
|
function to_destructured(node) {
|
||||||
if (node instanceof AST_Array) {
|
if (node instanceof AST_Array) {
|
||||||
|
var rest = null;
|
||||||
|
if (node.elements[node.elements.length - 1] instanceof AST_Spread) {
|
||||||
|
rest = to_destructured(node.elements.pop().expression);
|
||||||
|
if (!(rest instanceof AST_Destructured || is_assignable(rest))) return node;
|
||||||
|
}
|
||||||
var elements = node.elements.map(to_destructured);
|
var elements = node.elements.map(to_destructured);
|
||||||
return all(elements, function(node) {
|
return all(elements, function(node) {
|
||||||
return node instanceof AST_Destructured || node instanceof AST_Hole || is_assignable(node);
|
return node instanceof AST_DefaultValue
|
||||||
|
|| node instanceof AST_Destructured
|
||||||
|
|| node instanceof AST_Hole
|
||||||
|
|| is_assignable(node);
|
||||||
}) ? new AST_DestructuredArray({
|
}) ? new AST_DestructuredArray({
|
||||||
start: node.start,
|
start: node.start,
|
||||||
elements: elements,
|
elements: elements,
|
||||||
|
rest: rest,
|
||||||
|
end: node.end,
|
||||||
|
}) : node;
|
||||||
|
}
|
||||||
|
if (node instanceof AST_Assign) {
|
||||||
|
var name = to_destructured(node.left);
|
||||||
|
return name instanceof AST_Destructured || is_assignable(name) ? new AST_DefaultValue({
|
||||||
|
start: node.start,
|
||||||
|
name: name,
|
||||||
|
value: node.right,
|
||||||
end: node.end,
|
end: node.end,
|
||||||
}) : node;
|
}) : node;
|
||||||
}
|
}
|
||||||
if (!(node instanceof AST_Object)) return node;
|
if (!(node instanceof AST_Object)) return node;
|
||||||
|
var rest = null;
|
||||||
|
if (node.properties[node.properties.length - 1] instanceof AST_Spread) {
|
||||||
|
rest = to_destructured(node.properties.pop().expression);
|
||||||
|
if (!(rest instanceof AST_Destructured || is_assignable(rest))) return node;
|
||||||
|
}
|
||||||
var props = [];
|
var props = [];
|
||||||
for (var i = 0; i < node.properties.length; i++) {
|
for (var i = 0; i < node.properties.length; i++) {
|
||||||
var prop = node.properties[i];
|
var prop = node.properties[i];
|
||||||
if (!(prop instanceof AST_ObjectKeyVal)) return node;
|
if (!(prop instanceof AST_ObjectKeyVal)) return node;
|
||||||
var value = to_destructured(prop.value);
|
var value = to_destructured(prop.value);
|
||||||
if (!(value instanceof AST_Destructured || is_assignable(value))) return node;
|
if (!(value instanceof AST_DefaultValue || value instanceof AST_Destructured || is_assignable(value))) {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
props.push(new AST_DestructuredKeyVal({
|
props.push(new AST_DestructuredKeyVal({
|
||||||
start: prop.start,
|
start: prop.start,
|
||||||
key: prop.key,
|
key: prop.key,
|
||||||
@@ -1657,11 +1953,12 @@ function parse($TEXT, options) {
|
|||||||
return new AST_DestructuredObject({
|
return new AST_DestructuredObject({
|
||||||
start: node.start,
|
start: node.start,
|
||||||
properties: props,
|
properties: props,
|
||||||
|
rest: rest,
|
||||||
end: node.end,
|
end: node.end,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var maybe_assign = function(no_in) {
|
function maybe_assign(no_in) {
|
||||||
var start = S.token;
|
var start = S.token;
|
||||||
var left = maybe_conditional(no_in), val = S.token.value;
|
var left = maybe_conditional(no_in), val = S.token.value;
|
||||||
if (is("operator") && ASSIGNMENT[val]) {
|
if (is("operator") && ASSIGNMENT[val]) {
|
||||||
@@ -1678,23 +1975,28 @@ function parse($TEXT, options) {
|
|||||||
croak("Invalid assignment");
|
croak("Invalid assignment");
|
||||||
}
|
}
|
||||||
return left;
|
return left;
|
||||||
};
|
}
|
||||||
|
|
||||||
var expression = function(commas, no_in) {
|
function expression(no_in, maybe_arrow) {
|
||||||
var start = S.token;
|
var start = S.token;
|
||||||
var exprs = [];
|
var exprs = [];
|
||||||
while (true) {
|
while (true) {
|
||||||
|
if (maybe_arrow && is("operator", "...")) {
|
||||||
|
next();
|
||||||
|
exprs.rest = maybe_destructured(AST_SymbolFunarg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
exprs.push(maybe_assign(no_in));
|
exprs.push(maybe_assign(no_in));
|
||||||
if (!commas || !is("punc", ",")) break;
|
if (!is("punc", ",")) break;
|
||||||
next();
|
next();
|
||||||
commas = true;
|
if (maybe_arrow && is("punc", ")") && is_token(peek(), "punc", "=>")) break;
|
||||||
}
|
}
|
||||||
return exprs.length == 1 ? exprs[0] : new AST_Sequence({
|
return exprs.length == 1 && !exprs.rest ? exprs[0] : new AST_Sequence({
|
||||||
start : start,
|
start: start,
|
||||||
expressions : exprs,
|
expressions: exprs,
|
||||||
end : peek()
|
end: prev(),
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
function in_loop(cont) {
|
function in_loop(cont) {
|
||||||
++S.in_loop;
|
++S.in_loop;
|
||||||
@@ -1705,7 +2007,9 @@ function parse($TEXT, options) {
|
|||||||
|
|
||||||
if (options.expression) {
|
if (options.expression) {
|
||||||
handle_regexp();
|
handle_regexp();
|
||||||
return expression(true);
|
var exp = expression();
|
||||||
|
expect_token("eof");
|
||||||
|
return exp;
|
||||||
}
|
}
|
||||||
|
|
||||||
return function() {
|
return function() {
|
||||||
|
|||||||
@@ -228,7 +228,7 @@ function mangle_properties(ast, options) {
|
|||||||
var mangled = cache.get(name);
|
var mangled = cache.get(name);
|
||||||
if (!mangled) {
|
if (!mangled) {
|
||||||
if (debug) {
|
if (debug) {
|
||||||
// debug mode: use a prefix and suffix to preserve readability, e.g. o.foo -> o._$foo$NNN_.
|
// debug mode: use a prefix and suffix to preserve readability, e.g. o.foo ---> o._$foo$NNN_.
|
||||||
var debug_mangled = "_$" + name + "$" + debug_suffix + "_";
|
var debug_mangled = "_$" + name + "$" + debug_suffix + "_";
|
||||||
if (can_mangle(debug_mangled)) mangled = debug_mangled;
|
if (can_mangle(debug_mangled)) mangled = debug_mangled;
|
||||||
}
|
}
|
||||||
|
|||||||
111
lib/scope.js
111
lib/scope.js
@@ -48,7 +48,6 @@ function SymbolDef(id, scope, orig, init) {
|
|||||||
this.global = false;
|
this.global = false;
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.init = init;
|
this.init = init;
|
||||||
this.lambda = orig instanceof AST_SymbolLambda;
|
|
||||||
this.mangled_name = null;
|
this.mangled_name = null;
|
||||||
this.name = orig.name;
|
this.name = orig.name;
|
||||||
this.orig = [ orig ];
|
this.orig = [ orig ];
|
||||||
@@ -100,6 +99,8 @@ SymbolDef.prototype = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var unary_side_effects = makePredicate("delete ++ --");
|
||||||
|
|
||||||
AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
||||||
options = defaults(options, {
|
options = defaults(options, {
|
||||||
cache: null,
|
cache: null,
|
||||||
@@ -112,12 +113,13 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
|||||||
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 (node instanceof AST_Defun) {
|
if (is_defun(node)) {
|
||||||
node.name.walk(tw);
|
node.name.walk(tw);
|
||||||
walk_scope(function() {
|
walk_scope(function() {
|
||||||
node.argnames.forEach(function(argname) {
|
node.argnames.forEach(function(argname) {
|
||||||
argname.walk(tw);
|
argname.walk(tw);
|
||||||
});
|
});
|
||||||
|
if (node.rest) node.rest.walk(tw);
|
||||||
walk_body(node, tw);
|
walk_body(node, tw);
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
@@ -190,7 +192,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
|||||||
function entangle(defun, scope) {
|
function entangle(defun, scope) {
|
||||||
if (defun === scope) return;
|
if (defun === scope) return;
|
||||||
node.mark_enclosed(options);
|
node.mark_enclosed(options);
|
||||||
var def = scope.find_variable(node);
|
var def = scope.find_variable(node.name);
|
||||||
if (node.thedef === def) return;
|
if (node.thedef === def) return;
|
||||||
node.thedef = def;
|
node.thedef = def;
|
||||||
def.orig.push(node);
|
def.orig.push(node);
|
||||||
@@ -206,19 +208,48 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
|||||||
self.globals = new Dictionary();
|
self.globals = new Dictionary();
|
||||||
var in_arg = [];
|
var in_arg = [];
|
||||||
var tw = new TreeWalker(function(node) {
|
var tw = new TreeWalker(function(node) {
|
||||||
|
if (node instanceof AST_Catch) {
|
||||||
|
if (!(node.argname instanceof AST_Destructured)) return;
|
||||||
|
in_arg.push(node);
|
||||||
|
node.argname.walk(tw);
|
||||||
|
in_arg.pop();
|
||||||
|
walk_body(node, tw);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (node instanceof AST_Lambda) {
|
if (node instanceof AST_Lambda) {
|
||||||
in_arg.push(node);
|
in_arg.push(node);
|
||||||
node.argnames.forEach(function(argname) {
|
node.argnames.forEach(function(argname) {
|
||||||
argname.walk(tw);
|
argname.walk(tw);
|
||||||
});
|
});
|
||||||
|
if (node.rest) node.rest.walk(tw);
|
||||||
in_arg.pop();
|
in_arg.pop();
|
||||||
walk_body(node, tw);
|
walk_lambda(node, tw);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (node instanceof AST_LoopControl) {
|
if (node instanceof AST_LoopControl) {
|
||||||
if (node.label) node.label.thedef.references.push(node);
|
if (node.label) node.label.thedef.references.push(node);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (node instanceof AST_SymbolDeclaration) {
|
||||||
|
if (node instanceof AST_SymbolCatch) {
|
||||||
|
// ensure mangling works if `catch` reuses a scope variable
|
||||||
|
var def = node.definition().redefined();
|
||||||
|
if (def) for (var s = node.scope; s; s = s.parent_scope) {
|
||||||
|
push_uniq(s.enclosed, def);
|
||||||
|
if (s === def.scope) break;
|
||||||
|
}
|
||||||
|
} else if (node instanceof AST_SymbolConst) {
|
||||||
|
// ensure compression works if `const` reuses a scope variable
|
||||||
|
var redef = node.definition().redefined();
|
||||||
|
if (redef) redef.const_redefs = true;
|
||||||
|
}
|
||||||
|
if (node.name != "arguments") return true;
|
||||||
|
var parent = node instanceof AST_SymbolVar && tw.parent();
|
||||||
|
if (parent instanceof AST_VarDef && !parent.value) return true;
|
||||||
|
var sym = node.scope.resolve().find_variable("arguments");
|
||||||
|
if (sym && is_arguments(sym)) sym.scope.uses_arguments = 3;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (node instanceof AST_SymbolRef) {
|
if (node instanceof AST_SymbolRef) {
|
||||||
var name = node.name;
|
var name = node.name;
|
||||||
var sym = node.scope.find_variable(name);
|
var sym = node.scope.find_variable(name);
|
||||||
@@ -226,7 +257,9 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
|||||||
i = in_arg.lastIndexOf(sym.scope, i - 1);
|
i = in_arg.lastIndexOf(sym.scope, i - 1);
|
||||||
if (i < 0) break;
|
if (i < 0) break;
|
||||||
var decl = sym.orig[0];
|
var decl = sym.orig[0];
|
||||||
if (decl instanceof AST_SymbolFunarg || decl instanceof AST_SymbolLambda) {
|
if (decl instanceof AST_SymbolCatch
|
||||||
|
|| decl instanceof AST_SymbolFunarg
|
||||||
|
|| decl instanceof AST_SymbolLambda) {
|
||||||
node.in_arg = true;
|
node.in_arg = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -234,9 +267,14 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
|||||||
}
|
}
|
||||||
if (!sym) {
|
if (!sym) {
|
||||||
sym = self.def_global(node);
|
sym = self.def_global(node);
|
||||||
} else if (name == "arguments" && sym.scope instanceof AST_Lambda) {
|
} else if (name == "arguments" && is_arguments(sym)) {
|
||||||
if (!(tw.parent() instanceof AST_PropAccess)) {
|
var parent = tw.parent();
|
||||||
sym.scope.uses_arguments = "d";
|
if (parent instanceof AST_Assign && parent.left === node
|
||||||
|
|| parent instanceof AST_Unary && unary_side_effects[parent.operator]) {
|
||||||
|
sym.scope.uses_arguments = 3;
|
||||||
|
} else if (sym.scope.uses_arguments < 2
|
||||||
|
&& !(parent instanceof AST_PropAccess && parent.expression === node)) {
|
||||||
|
sym.scope.uses_arguments = 2;
|
||||||
} else if (!sym.scope.uses_arguments) {
|
} else if (!sym.scope.uses_arguments) {
|
||||||
sym.scope.uses_arguments = true;
|
sym.scope.uses_arguments = true;
|
||||||
}
|
}
|
||||||
@@ -258,21 +296,6 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
|||||||
node.reference(options);
|
node.reference(options);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// ensure mangling works if `catch` reuses a scope variable
|
|
||||||
if (node instanceof AST_SymbolCatch) {
|
|
||||||
var def = node.definition().redefined();
|
|
||||||
if (def) for (var s = node.scope; s; s = s.parent_scope) {
|
|
||||||
push_uniq(s.enclosed, def);
|
|
||||||
if (s === def.scope) break;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// ensure compression works if `const` reuses a scope variable
|
|
||||||
if (node instanceof AST_SymbolConst) {
|
|
||||||
var redef = node.definition().redefined();
|
|
||||||
if (redef) redef.const_redefs = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
self.walk(tw);
|
self.walk(tw);
|
||||||
|
|
||||||
@@ -288,8 +311,9 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
|||||||
}
|
}
|
||||||
if (node instanceof AST_SymbolLambda) {
|
if (node instanceof AST_SymbolLambda) {
|
||||||
var def = node.thedef;
|
var def = node.thedef;
|
||||||
redefine(node, node.scope.parent_scope.resolve());
|
if (!redefine(node, node.scope.parent_scope.resolve())) {
|
||||||
if (typeof node.thedef.init !== "undefined") {
|
delete def.defun;
|
||||||
|
} else if (typeof node.thedef.init !== "undefined") {
|
||||||
node.thedef.init = false;
|
node.thedef.init = false;
|
||||||
} else if (def.init) {
|
} else if (def.init) {
|
||||||
node.thedef.init = def.init;
|
node.thedef.init = def.init;
|
||||||
@@ -298,12 +322,18 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
function is_arguments(sym) {
|
||||||
|
return sym.orig[0] instanceof AST_SymbolFunarg
|
||||||
|
&& !(sym.orig[1] instanceof AST_SymbolFunarg || sym.orig[2] instanceof AST_SymbolFunarg)
|
||||||
|
&& !is_arrow(sym.scope);
|
||||||
|
}
|
||||||
|
|
||||||
function redefine(node, scope) {
|
function redefine(node, scope) {
|
||||||
var name = node.name;
|
var name = node.name;
|
||||||
var old_def = node.thedef;
|
var old_def = node.thedef;
|
||||||
if (!all(old_def.orig, function(sym) {
|
if (!all(old_def.orig, function(sym) {
|
||||||
return !(sym instanceof AST_SymbolConst || sym instanceof AST_SymbolLet);
|
return !(sym instanceof AST_SymbolConst || sym instanceof AST_SymbolLet);
|
||||||
})) return;
|
})) return false;
|
||||||
var new_def = scope.find_variable(name);
|
var new_def = scope.find_variable(name);
|
||||||
if (new_def) {
|
if (new_def) {
|
||||||
var redef = new_def.redefined();
|
var redef = new_def.redefined();
|
||||||
@@ -318,12 +348,12 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
|||||||
}
|
}
|
||||||
old_def.defun = new_def.scope;
|
old_def.defun = new_def.scope;
|
||||||
old_def.forEach(function(node) {
|
old_def.forEach(function(node) {
|
||||||
node.redef = true;
|
node.redef = old_def;
|
||||||
node.thedef = new_def;
|
node.thedef = new_def;
|
||||||
node.reference(options);
|
node.reference(options);
|
||||||
});
|
});
|
||||||
if (old_def.lambda) new_def.lambda = true;
|
|
||||||
if (new_def.undeclared) self.variables.set(name, new_def);
|
if (new_def.undeclared) self.variables.set(name, new_def);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -360,6 +390,12 @@ AST_BlockScope.DEFMETHOD("init_vars", function(parent_scope) {
|
|||||||
AST_Scope.DEFMETHOD("init_vars", function(parent_scope) {
|
AST_Scope.DEFMETHOD("init_vars", function(parent_scope) {
|
||||||
init_scope_vars(this, parent_scope);
|
init_scope_vars(this, parent_scope);
|
||||||
});
|
});
|
||||||
|
AST_Arrow.DEFMETHOD("init_vars", function(parent_scope) {
|
||||||
|
init_scope_vars(this, parent_scope);
|
||||||
|
});
|
||||||
|
AST_AsyncArrow.DEFMETHOD("init_vars", function(parent_scope) {
|
||||||
|
init_scope_vars(this, parent_scope);
|
||||||
|
});
|
||||||
AST_Lambda.DEFMETHOD("init_vars", function(parent_scope) {
|
AST_Lambda.DEFMETHOD("init_vars", function(parent_scope) {
|
||||||
init_scope_vars(this, parent_scope);
|
init_scope_vars(this, parent_scope);
|
||||||
this.uses_arguments = false;
|
this.uses_arguments = false;
|
||||||
@@ -390,14 +426,13 @@ AST_Symbol.DEFMETHOD("reference", function(options) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
AST_BlockScope.DEFMETHOD("find_variable", function(name) {
|
AST_BlockScope.DEFMETHOD("find_variable", function(name) {
|
||||||
if (name instanceof AST_Symbol) name = name.name;
|
|
||||||
return this.variables.get(name)
|
return this.variables.get(name)
|
||||||
|| (this.parent_scope && this.parent_scope.find_variable(name));
|
|| this.parent_scope && this.parent_scope.find_variable(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 || def.init instanceof AST_Defun) def.init = init;
|
if (!def.init || is_defun(def.init)) def.init = init;
|
||||||
this.functions.set(symbol.name, def);
|
this.functions.set(symbol.name, def);
|
||||||
return def;
|
return def;
|
||||||
});
|
});
|
||||||
@@ -406,7 +441,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 (def.init instanceof AST_Function) def.init = init;
|
if (is_function(def.init)) 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);
|
||||||
@@ -486,6 +521,7 @@ function _default_mangler_options(options) {
|
|||||||
keep_fnames : false,
|
keep_fnames : false,
|
||||||
reserved : [],
|
reserved : [],
|
||||||
toplevel : false,
|
toplevel : false,
|
||||||
|
v8 : false,
|
||||||
webkit : false,
|
webkit : false,
|
||||||
});
|
});
|
||||||
if (!Array.isArray(options.reserved)) options.reserved = [];
|
if (!Array.isArray(options.reserved)) options.reserved = [];
|
||||||
@@ -517,7 +553,7 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
|
|||||||
// lname is incremented when we get to the AST_Label
|
// lname is incremented when we get to the AST_Label
|
||||||
var save_nesting = lname;
|
var save_nesting = lname;
|
||||||
descend();
|
descend();
|
||||||
lname = save_nesting;
|
if (!options.v8 || !in_label(tw)) lname = save_nesting;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (node instanceof AST_BlockScope) {
|
if (node instanceof AST_BlockScope) {
|
||||||
@@ -576,6 +612,7 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
|
|||||||
if (!(sym instanceof AST_SymbolConst)) return false;
|
if (!(sym instanceof AST_SymbolConst)) return false;
|
||||||
var scope = def.scope.resolve();
|
var scope = def.scope.resolve();
|
||||||
if (def.scope === scope) return false;
|
if (def.scope === scope) return false;
|
||||||
|
if (def.scope.parent_scope.find_variable(sym.name)) return false;
|
||||||
redef = scope.def_variable(sym);
|
redef = scope.def_variable(sym);
|
||||||
scope.to_mangle.push(redef);
|
scope.to_mangle.push(redef);
|
||||||
}
|
}
|
||||||
@@ -590,6 +627,14 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
|
|||||||
sym.thedef = def;
|
sym.thedef = def;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function in_label(tw) {
|
||||||
|
var level = 0, parent;
|
||||||
|
while (parent = tw.parent(level++)) {
|
||||||
|
if (parent instanceof AST_Block) return parent instanceof AST_Toplevel && !options.toplevel;
|
||||||
|
if (parent instanceof AST_LabeledStatement) return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Toplevel.DEFMETHOD("find_colliding_names", function(options) {
|
AST_Toplevel.DEFMETHOD("find_colliding_names", function(options) {
|
||||||
|
|||||||
@@ -144,7 +144,9 @@ function SourceMap(options) {
|
|||||||
add(source, gen_line, gen_col, orig_line, orig_col, name);
|
add(source, gen_line, gen_col, orig_line, orig_col, name);
|
||||||
} : add,
|
} : add,
|
||||||
setSourceContent: sources_content ? function(source, content) {
|
setSourceContent: sources_content ? function(source, content) {
|
||||||
sources_content[source] = content;
|
if (!(source in sources_content)) {
|
||||||
|
sources_content[source] = content;
|
||||||
|
}
|
||||||
} : noop,
|
} : noop,
|
||||||
toString: function() {
|
toString: function() {
|
||||||
return JSON.stringify({
|
return JSON.stringify({
|
||||||
|
|||||||
@@ -126,11 +126,27 @@ TreeTransformer.prototype = new TreeWalker;
|
|||||||
self.name = self.name.transform(tw);
|
self.name = self.name.transform(tw);
|
||||||
if (self.value) self.value = self.value.transform(tw);
|
if (self.value) self.value = self.value.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_DefaultValue, function(self, tw) {
|
||||||
|
self.name = self.name.transform(tw);
|
||||||
|
self.value = self.value.transform(tw);
|
||||||
|
});
|
||||||
DEF(AST_Lambda, function(self, tw) {
|
DEF(AST_Lambda, function(self, tw) {
|
||||||
if (self.name) self.name = self.name.transform(tw);
|
if (self.name) self.name = self.name.transform(tw);
|
||||||
self.argnames = do_list(self.argnames, tw);
|
self.argnames = do_list(self.argnames, tw);
|
||||||
|
if (self.rest) self.rest = self.rest.transform(tw);
|
||||||
self.body = do_list(self.body, tw);
|
self.body = do_list(self.body, tw);
|
||||||
});
|
});
|
||||||
|
function transform_arrow(self, tw) {
|
||||||
|
self.argnames = do_list(self.argnames, tw);
|
||||||
|
if (self.rest) self.rest = self.rest.transform(tw);
|
||||||
|
if (self.value) {
|
||||||
|
self.value = self.value.transform(tw);
|
||||||
|
} else {
|
||||||
|
self.body = do_list(self.body, tw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DEF(AST_Arrow, transform_arrow);
|
||||||
|
DEF(AST_AsyncArrow, transform_arrow);
|
||||||
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);
|
||||||
@@ -138,6 +154,9 @@ TreeTransformer.prototype = new TreeWalker;
|
|||||||
DEF(AST_Sequence, function(self, tw) {
|
DEF(AST_Sequence, function(self, tw) {
|
||||||
self.expressions = do_list(self.expressions, tw);
|
self.expressions = do_list(self.expressions, tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Await, function(self, tw) {
|
||||||
|
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);
|
||||||
});
|
});
|
||||||
@@ -145,6 +164,9 @@ TreeTransformer.prototype = new TreeWalker;
|
|||||||
self.expression = self.expression.transform(tw);
|
self.expression = self.expression.transform(tw);
|
||||||
self.property = self.property.transform(tw);
|
self.property = self.property.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Spread, function(self, tw) {
|
||||||
|
self.expression = self.expression.transform(tw);
|
||||||
|
});
|
||||||
DEF(AST_Unary, function(self, tw) {
|
DEF(AST_Unary, function(self, tw) {
|
||||||
self.expression = self.expression.transform(tw);
|
self.expression = self.expression.transform(tw);
|
||||||
});
|
});
|
||||||
@@ -162,6 +184,7 @@ TreeTransformer.prototype = new TreeWalker;
|
|||||||
});
|
});
|
||||||
DEF(AST_DestructuredArray, function(self, tw) {
|
DEF(AST_DestructuredArray, function(self, tw) {
|
||||||
self.elements = do_list(self.elements, tw);
|
self.elements = do_list(self.elements, tw);
|
||||||
|
if (self.rest) self.rest = self.rest.transform(tw);
|
||||||
});
|
});
|
||||||
DEF(AST_DestructuredKeyVal, function(self, tw) {
|
DEF(AST_DestructuredKeyVal, function(self, tw) {
|
||||||
if (self.key instanceof AST_Node) self.key = self.key.transform(tw);
|
if (self.key instanceof AST_Node) self.key = self.key.transform(tw);
|
||||||
@@ -169,6 +192,7 @@ TreeTransformer.prototype = new TreeWalker;
|
|||||||
});
|
});
|
||||||
DEF(AST_DestructuredObject, function(self, tw) {
|
DEF(AST_DestructuredObject, function(self, tw) {
|
||||||
self.properties = do_list(self.properties, tw);
|
self.properties = do_list(self.properties, tw);
|
||||||
|
if (self.rest) self.rest = self.rest.transform(tw);
|
||||||
});
|
});
|
||||||
DEF(AST_Object, function(self, tw) {
|
DEF(AST_Object, function(self, tw) {
|
||||||
self.properties = do_list(self.properties, tw);
|
self.properties = do_list(self.properties, tw);
|
||||||
|
|||||||
@@ -238,13 +238,15 @@ 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) {
|
function first_in_statement(stack, arrow) {
|
||||||
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 (p.TYPE == "Call") {
|
if (is_arrow(p)) {
|
||||||
if (p.expression === node) continue;
|
return arrow && p.value === node;
|
||||||
} else if (p instanceof AST_Binary) {
|
} else if (p instanceof AST_Binary) {
|
||||||
if (p.left === node) continue;
|
if (p.left === node) continue;
|
||||||
|
} else if (p.TYPE == "Call") {
|
||||||
|
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_PropAccess) {
|
} else if (p instanceof AST_PropAccess) {
|
||||||
|
|||||||
@@ -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.1",
|
"version": "3.12.6",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
require("../tools/exit");
|
require("../tools/tty");
|
||||||
|
|
||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
var child_process = require("child_process");
|
var child_process = require("child_process");
|
||||||
@@ -209,7 +209,7 @@ function reminify(orig_options, input_code, input_formatted, stdout) {
|
|||||||
} else {
|
} else {
|
||||||
var toplevel = sandbox.has_toplevel(options);
|
var toplevel = sandbox.has_toplevel(options);
|
||||||
var expected = stdout[toplevel ? 1 : 0];
|
var expected = stdout[toplevel ? 1 : 0];
|
||||||
var actual = run_code(result.code, toplevel);
|
var actual = sandbox.run_code(result.code, toplevel);
|
||||||
if (typeof expected != "string" && typeof actual != "string" && expected.name == actual.name) {
|
if (typeof expected != "string" && typeof actual != "string" && expected.name == actual.name) {
|
||||||
actual = expected;
|
actual = expected;
|
||||||
}
|
}
|
||||||
@@ -244,11 +244,6 @@ function reminify(orig_options, input_code, input_formatted, stdout) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function run_code(code, toplevel) {
|
|
||||||
var result = sandbox.run_code(code, toplevel);
|
|
||||||
return typeof result == "string" ? result.replace(/\u001b\[\d+m/g, "") : result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function test_case(test) {
|
function test_case(test) {
|
||||||
log(" Running test [{name}]", { name: test.name });
|
log(" Running test [{name}]", { name: test.name });
|
||||||
U.AST_Node.enable_validation();
|
U.AST_Node.enable_validation();
|
||||||
@@ -380,7 +375,7 @@ function test_case(test) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (test.expect_stdout && (!test.node_version || semver.satisfies(process.version, test.node_version))) {
|
if (test.expect_stdout && (!test.node_version || semver.satisfies(process.version, test.node_version))) {
|
||||||
var stdout = [ run_code(input_code), run_code(input_code, true) ];
|
var stdout = [ sandbox.run_code(input_code), sandbox.run_code(input_code, true) ];
|
||||||
var toplevel = sandbox.has_toplevel({
|
var toplevel = sandbox.has_toplevel({
|
||||||
compress: test.options,
|
compress: test.options,
|
||||||
mangle: test.mangle
|
mangle: test.mangle
|
||||||
@@ -409,7 +404,7 @@ function test_case(test) {
|
|||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
actual = run_code(output_code, toplevel);
|
actual = sandbox.run_code(output_code, toplevel);
|
||||||
if (!sandbox.same_stdout(test.expect_stdout, actual)) {
|
if (!sandbox.same_stdout(test.expect_stdout, actual)) {
|
||||||
log([
|
log([
|
||||||
"!!! failed",
|
"!!! failed",
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ replace_index_strict: {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
replace_index_keep_fargs: {
|
replace_index_drop_fargs_1: {
|
||||||
options = {
|
options = {
|
||||||
arguments: true,
|
arguments: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
@@ -101,6 +101,13 @@ replace_index_keep_fargs: {
|
|||||||
var arguments;
|
var arguments;
|
||||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||||
})("bar", 42);
|
})("bar", 42);
|
||||||
|
(function() {
|
||||||
|
var arguments = {
|
||||||
|
1: "foo",
|
||||||
|
foo: "bar",
|
||||||
|
};
|
||||||
|
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||||
|
})("bar", 42);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var arguments = [];
|
var arguments = [];
|
||||||
@@ -114,8 +121,15 @@ replace_index_keep_fargs: {
|
|||||||
(function(arguments) {
|
(function(arguments) {
|
||||||
console.log(arguments[1], arguments[1], arguments.foo);
|
console.log(arguments[1], arguments[1], arguments.foo);
|
||||||
})("bar", 42);
|
})("bar", 42);
|
||||||
(function() {
|
(function(argument_0, argument_1) {
|
||||||
var arguments;
|
var arguments;
|
||||||
|
console.log(argument_1, argument_1, arguments.foo);
|
||||||
|
})("bar", 42);
|
||||||
|
(function() {
|
||||||
|
var arguments = {
|
||||||
|
1: "foo",
|
||||||
|
foo: "bar",
|
||||||
|
};
|
||||||
console.log(arguments[1], arguments[1], arguments.foo);
|
console.log(arguments[1], arguments[1], arguments.foo);
|
||||||
})("bar", 42);
|
})("bar", 42);
|
||||||
}
|
}
|
||||||
@@ -125,10 +139,11 @@ replace_index_keep_fargs: {
|
|||||||
"42 42 undefined",
|
"42 42 undefined",
|
||||||
"a a undefined",
|
"a a undefined",
|
||||||
"42 42 undefined",
|
"42 42 undefined",
|
||||||
|
"foo foo bar",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
replace_index_keep_fargs_strict: {
|
replace_index_drop_fargs_2: {
|
||||||
options = {
|
options = {
|
||||||
arguments: true,
|
arguments: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
@@ -412,7 +427,7 @@ issue_3273_global_strict_reduce_vars: {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_3273_keep_fargs_false: {
|
issue_3273_drop_fargs_1: {
|
||||||
options = {
|
options = {
|
||||||
arguments: true,
|
arguments: true,
|
||||||
keep_fargs: false,
|
keep_fargs: false,
|
||||||
@@ -435,10 +450,10 @@ issue_3273_keep_fargs_false: {
|
|||||||
expect_stdout: "1"
|
expect_stdout: "1"
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_3273_keep_fargs_strict: {
|
issue_3273_drop_fargs_2: {
|
||||||
options = {
|
options = {
|
||||||
arguments: true,
|
arguments: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -633,7 +648,7 @@ issue_3282_2_passes: {
|
|||||||
issue_3420_1: {
|
issue_3420_1: {
|
||||||
options = {
|
options = {
|
||||||
arguments: true,
|
arguments: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
console.log(function() {
|
console.log(function() {
|
||||||
@@ -655,7 +670,7 @@ issue_3420_1: {
|
|||||||
issue_3420_2: {
|
issue_3420_2: {
|
||||||
options = {
|
options = {
|
||||||
arguments: true,
|
arguments: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var foo = function() {
|
var foo = function() {
|
||||||
@@ -675,7 +690,7 @@ issue_3420_2: {
|
|||||||
issue_3420_3: {
|
issue_3420_3: {
|
||||||
options = {
|
options = {
|
||||||
arguments: true,
|
arguments: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
"use strict";
|
"use strict";
|
||||||
@@ -697,7 +712,7 @@ issue_3420_3: {
|
|||||||
issue_3420_4: {
|
issue_3420_4: {
|
||||||
options = {
|
options = {
|
||||||
arguments: true,
|
arguments: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
!function() {
|
!function() {
|
||||||
@@ -722,7 +737,7 @@ issue_3420_4: {
|
|||||||
issue_3420_5: {
|
issue_3420_5: {
|
||||||
options = {
|
options = {
|
||||||
arguments: true,
|
arguments: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
"use strict";
|
"use strict";
|
||||||
@@ -749,7 +764,7 @@ issue_3420_5: {
|
|||||||
issue_3420_6: {
|
issue_3420_6: {
|
||||||
options = {
|
options = {
|
||||||
arguments: true,
|
arguments: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
console.log(function() {
|
console.log(function() {
|
||||||
@@ -767,7 +782,7 @@ issue_3420_6: {
|
|||||||
issue_3420_7: {
|
issue_3420_7: {
|
||||||
options = {
|
options = {
|
||||||
arguments: true,
|
arguments: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
"use strict";
|
"use strict";
|
||||||
@@ -811,7 +826,7 @@ issue_4200: {
|
|||||||
issue_4291_1: {
|
issue_4291_1: {
|
||||||
options = {
|
options = {
|
||||||
arguments: true,
|
arguments: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
console.log(function() {
|
console.log(function() {
|
||||||
@@ -831,7 +846,7 @@ issue_4291_1: {
|
|||||||
issue_4291_2: {
|
issue_4291_2: {
|
||||||
options = {
|
options = {
|
||||||
arguments: true,
|
arguments: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = function() {
|
var a = function() {
|
||||||
@@ -851,3 +866,114 @@ issue_4291_2: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS 42 1"
|
expect_stdout: "PASS 42 1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4397: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(typeof function() {
|
||||||
|
arguments += 0;
|
||||||
|
return arguments[0];
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(typeof function() {
|
||||||
|
arguments += 0;
|
||||||
|
return arguments[0];
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "string"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4410_1: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
conditionals: true,
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a) {
|
||||||
|
console.log(arguments[0] === (a = 0) ? "FAIL" : "PASS");
|
||||||
|
})(1);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a) {
|
||||||
|
console.log(a === (a = 0) ? "FAIL" : "PASS");
|
||||||
|
})(1);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4410_2: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
conditionals: true,
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function f(a) {
|
||||||
|
console.log(arguments[0] === (a = 0) ? "FAIL" : "PASS");
|
||||||
|
})(1);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function f(a) {
|
||||||
|
console.log(arguments[0] === (a = 0) ? "FAIL" : "PASS");
|
||||||
|
})(1);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4410_3: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 1;
|
||||||
|
(function f(b) {
|
||||||
|
a-- && f();
|
||||||
|
for (var c = 2; c--;)
|
||||||
|
switch (arguments[0]) {
|
||||||
|
case b = 42:
|
||||||
|
case 42:
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
})(null);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 1;
|
||||||
|
(function f(b) {
|
||||||
|
a-- && f();
|
||||||
|
for (var c = 2; c--;)
|
||||||
|
switch (arguments[0]) {
|
||||||
|
case b = 42:
|
||||||
|
case 42:
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
})(null);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4432: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a) {
|
||||||
|
for (a in { FAIL: 42 });
|
||||||
|
return arguments[0];
|
||||||
|
}() || "PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a) {
|
||||||
|
for (a in { FAIL: 42 });
|
||||||
|
return arguments[0];
|
||||||
|
}() || "PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -13,9 +13,10 @@ holes_and_undefined: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constant_join: {
|
constant_join_1: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
side_effects: true,
|
||||||
strings: true,
|
strings: true,
|
||||||
unsafe: true,
|
unsafe: true,
|
||||||
}
|
}
|
||||||
@@ -57,7 +58,7 @@ constant_join: {
|
|||||||
var c5 = [ boo() + bar() + "foo", 1, 2, 3, "bar", bar() + "foo" ].join();
|
var c5 = [ boo() + bar() + "foo", 1, 2, 3, "bar", bar() + "foo" ].join();
|
||||||
var c6 = [ "1,2,,,foo,bar", baz() ].join();
|
var c6 = [ "1,2,,,foo,bar", baz() ].join();
|
||||||
var d = "foo-3bar-baz";
|
var d = "foo-3bar-baz";
|
||||||
var e = [].join(foo + bar);
|
var e = (foo, bar, "");
|
||||||
var f = "";
|
var f = "";
|
||||||
var g = "";
|
var g = "";
|
||||||
}
|
}
|
||||||
|
|||||||
640
test/compress/arrows.js
Normal file
640
test/compress/arrows.js
Normal file
@@ -0,0 +1,640 @@
|
|||||||
|
no_funarg: {
|
||||||
|
input: {
|
||||||
|
(() => console.log(42))();
|
||||||
|
}
|
||||||
|
expect_exact: "(()=>console.log(42))();"
|
||||||
|
expect_stdout: "42"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
single_funarg: {
|
||||||
|
input: {
|
||||||
|
(a => console.log(a))(42);
|
||||||
|
}
|
||||||
|
expect_exact: "(a=>console.log(a))(42);"
|
||||||
|
expect_stdout: "42"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
multiple_funargs: {
|
||||||
|
input: {
|
||||||
|
((a, b) => console.log(a, b))("foo", "bar");
|
||||||
|
}
|
||||||
|
expect_exact: '((a,b)=>console.log(a,b))("foo","bar");'
|
||||||
|
expect_stdout: "foo bar"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
destructured_funarg: {
|
||||||
|
input: {
|
||||||
|
(([ a, b, c ]) => console.log(a, b, c))("foo");
|
||||||
|
}
|
||||||
|
expect_exact: '(([a,b,c])=>console.log(a,b,c))("foo");'
|
||||||
|
expect_stdout: "f o o"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
await_parenthesis: {
|
||||||
|
input: {
|
||||||
|
async function f() {
|
||||||
|
await (a => a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_exact: "async function f(){await(a=>a)}"
|
||||||
|
}
|
||||||
|
|
||||||
|
for_parenthesis_init: {
|
||||||
|
input: {
|
||||||
|
for (a => (a in a); console.log(42););
|
||||||
|
}
|
||||||
|
expect_exact: "for((a=>a in a);console.log(42););"
|
||||||
|
expect_stdout: "42"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
for_parenthesis_condition: {
|
||||||
|
input: {
|
||||||
|
for (console.log(42); a => (a in a);)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
expect_exact: "for(console.log(42);a=>a in a;)break;"
|
||||||
|
expect_stdout: "42"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
for_parenthesis_step: {
|
||||||
|
input: {
|
||||||
|
for (; console.log(42); a => (a in a));
|
||||||
|
}
|
||||||
|
expect_exact: "for(;console.log(42);a=>a in a);"
|
||||||
|
expect_stdout: "42"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
for_assign_parenthesis_init: {
|
||||||
|
input: {
|
||||||
|
for (f = a => (a in a); console.log(42););
|
||||||
|
}
|
||||||
|
expect_exact: "for((f=a=>a in a);console.log(42););"
|
||||||
|
expect_stdout: "42"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
for_assign_parenthesis_condition: {
|
||||||
|
input: {
|
||||||
|
for (console.log(42); f = a => (a in a);)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
expect_exact: "for(console.log(42);f=a=>a in a;)break;"
|
||||||
|
expect_stdout: "42"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
for_assign_parenthesis_step: {
|
||||||
|
input: {
|
||||||
|
for (; console.log(42); f = a => (a in a));
|
||||||
|
}
|
||||||
|
expect_exact: "for(;console.log(42);f=a=>a in a);"
|
||||||
|
expect_stdout: "42"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
for_declaration_parenthesis_init: {
|
||||||
|
input: {
|
||||||
|
for (var f = a => (a in a); console.log(42););
|
||||||
|
}
|
||||||
|
expect_exact: "for(var f=(a=>a in a);console.log(42););"
|
||||||
|
expect_stdout: "42"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
for_statement_parenthesis_init: {
|
||||||
|
input: {
|
||||||
|
for (a => {
|
||||||
|
a in a;
|
||||||
|
}; console.log(42););
|
||||||
|
}
|
||||||
|
expect_exact: "for(a=>{a in a};console.log(42););"
|
||||||
|
expect_stdout: "42"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
body_call: {
|
||||||
|
input: {
|
||||||
|
(() => {
|
||||||
|
console.log("foo");
|
||||||
|
console.log("bar");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_exact: '(()=>{console.log("foo");console.log("bar")})();'
|
||||||
|
expect_stdout: [
|
||||||
|
"foo",
|
||||||
|
"bar",
|
||||||
|
]
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
body_conditional: {
|
||||||
|
input: {
|
||||||
|
console.log((a => {}) ? "PASS" : "FAIL");
|
||||||
|
}
|
||||||
|
expect_exact: 'console.log((a=>{})?"PASS":"FAIL");'
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
destructured_object_value: {
|
||||||
|
input: {
|
||||||
|
console.log((a => ({} = a))(42));
|
||||||
|
}
|
||||||
|
expect_exact: "console.log((a=>({}=a))(42));"
|
||||||
|
expect_stdout: "42"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
function_value: {
|
||||||
|
input: {
|
||||||
|
console.log((a => function() {
|
||||||
|
return a;
|
||||||
|
})(42)());
|
||||||
|
}
|
||||||
|
expect_exact: "console.log((a=>function(){return a})(42)());"
|
||||||
|
expect_stdout: "42"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
in_value: {
|
||||||
|
input: {
|
||||||
|
console.log((a => a in {
|
||||||
|
foo: 42,
|
||||||
|
})("foo"));
|
||||||
|
}
|
||||||
|
expect_exact: 'console.log((a=>a in{foo:42})("foo"));'
|
||||||
|
expect_stdout: "true"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
object_value: {
|
||||||
|
input: {
|
||||||
|
console.log((() => ({
|
||||||
|
4: 2,
|
||||||
|
}))()[4]);
|
||||||
|
}
|
||||||
|
expect_exact: "console.log((()=>({4:2}))()[4]);"
|
||||||
|
expect_stdout: "2"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
object_first_in_value: {
|
||||||
|
input: {
|
||||||
|
console.log((a => ({
|
||||||
|
p: a,
|
||||||
|
}.p ? "FAIL" : "PASS"))());
|
||||||
|
}
|
||||||
|
expect_exact: 'console.log((a=>({p:a}).p?"FAIL":"PASS")());'
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
sequence_value: {
|
||||||
|
input: {
|
||||||
|
console.log((a => (console.log("foo"), a))("bar"));
|
||||||
|
}
|
||||||
|
expect_exact: 'console.log((a=>(console.log("foo"),a))("bar"));'
|
||||||
|
expect_stdout: [
|
||||||
|
"foo",
|
||||||
|
"bar",
|
||||||
|
]
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
side_effects_value: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log((a => function() {
|
||||||
|
return a;
|
||||||
|
})(42)());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log((a => function() {
|
||||||
|
return a;
|
||||||
|
})(42)());
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
arrow_property: {
|
||||||
|
input: {
|
||||||
|
console.log((a => 42).prototype);
|
||||||
|
}
|
||||||
|
expect_exact: "console.log((a=>42).prototype);"
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
assign_arrow: {
|
||||||
|
input: {
|
||||||
|
var f = a => a;
|
||||||
|
console.log(f(42));
|
||||||
|
}
|
||||||
|
expect_exact: "var f=a=>a;console.log(f(42));"
|
||||||
|
expect_stdout: "42"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
binary_arrow: {
|
||||||
|
input: {
|
||||||
|
console.log(4 || (() => 2));
|
||||||
|
}
|
||||||
|
expect_exact: "console.log(4||(()=>2));"
|
||||||
|
expect_stdout: "4"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
unary_arrow: {
|
||||||
|
input: {
|
||||||
|
console.log(+(() => 42));
|
||||||
|
}
|
||||||
|
expect_exact: "console.log(+(()=>42));"
|
||||||
|
expect_stdout: "NaN"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
trailing_comma: {
|
||||||
|
input: {
|
||||||
|
((a,) => console.log(a))(42);
|
||||||
|
}
|
||||||
|
expect_exact: "(a=>console.log(a))(42);"
|
||||||
|
expect_stdout: "42"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_arguments: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
return () => arguments[0];
|
||||||
|
}("PASS")("FAIL"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(argument_0) {
|
||||||
|
return () => argument_0;
|
||||||
|
}("PASS")("FAIL"));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
funarg_arguments: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log((arguments => arguments)(42));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(42);
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
inline_arguments: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
return () => arguments[0];
|
||||||
|
}("PASS")("FAIL"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
return () => arguments[0];
|
||||||
|
}("PASS")("FAIL"));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
var_arguments: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
properties: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
return () => {
|
||||||
|
var arguments = [ "PASS" ];
|
||||||
|
return arguments;
|
||||||
|
};
|
||||||
|
}("FAIL 1")("FAIL 2")[0]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
negate: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
if (!console ? 0 : () => 1)
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(console ? () => 1 : 0) && console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
inline_this: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
p: function() {
|
||||||
|
return function() {
|
||||||
|
return () => this.q;
|
||||||
|
}();
|
||||||
|
},
|
||||||
|
q: "FAIL",
|
||||||
|
};
|
||||||
|
q = "PASS";
|
||||||
|
console.log(o.p()());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
p: function() {
|
||||||
|
return function() {
|
||||||
|
return () => this.q;
|
||||||
|
}();
|
||||||
|
},
|
||||||
|
q: "FAIL",
|
||||||
|
};
|
||||||
|
q = "PASS";
|
||||||
|
console.log(o.p()());
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
trim_body: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
if_return: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var f = a => {
|
||||||
|
return a;
|
||||||
|
};
|
||||||
|
var g = b => void b;
|
||||||
|
console.log(f("PASS"), g("FAIL"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var f = a => a;
|
||||||
|
var g = b => {};
|
||||||
|
console.log(f("PASS"), g("FAIL"));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS undefined"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
collapse_value: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 42;
|
||||||
|
console.log((b => Math.floor(b))(a));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 42;
|
||||||
|
console.log((() => Math.floor(a))());
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce_iife_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(a => console.log(a + a))(21);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(() => console.log(42))();
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce_iife_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 21;
|
||||||
|
(() => console.log(a + a))();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(() => console.log(42))();
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce_iife_3: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "foo";
|
||||||
|
(() => {
|
||||||
|
console.log(a);
|
||||||
|
console.log(a);
|
||||||
|
})();
|
||||||
|
a = "bar";
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(() => {
|
||||||
|
console.log("foo");
|
||||||
|
console.log("foo");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"foo",
|
||||||
|
"foo",
|
||||||
|
]
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
single_use_recursive: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
return (() => f)();
|
||||||
|
}
|
||||||
|
console.log(typeof f());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(typeof function f() {
|
||||||
|
return (() => f)();
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4388: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(arguments => console.log(arguments && arguments))();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(arguments => console.log(arguments && arguments))();
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4390: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function log() {
|
||||||
|
console.log.apply(console, arguments);
|
||||||
|
}
|
||||||
|
var a = 42, b = "FAIL";
|
||||||
|
b = "PASS";
|
||||||
|
(c => log(b, c))(a);
|
||||||
|
log(b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function log() {
|
||||||
|
console.log.apply(console, arguments);
|
||||||
|
}
|
||||||
|
var a = 42, b = "FAIL";
|
||||||
|
b = "PASS";
|
||||||
|
(c => log(b, c))(a);
|
||||||
|
log(b);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"PASS 42",
|
||||||
|
"PASS",
|
||||||
|
]
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4401: {
|
||||||
|
options = {
|
||||||
|
merge_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
var a = (b => b(a))(console.log || a);
|
||||||
|
var c = console.log;
|
||||||
|
c && c(typeof b);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
var a = (b => b(a))(console.log || a);
|
||||||
|
var c = console.log;
|
||||||
|
c && c(typeof b);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"undefined",
|
||||||
|
"undefined",
|
||||||
|
]
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4448: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var A;
|
||||||
|
try {
|
||||||
|
(arguments => {
|
||||||
|
arguments[0];
|
||||||
|
})(A);
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var A;
|
||||||
|
try {
|
||||||
|
(arguments => {
|
||||||
|
arguments[0];
|
||||||
|
})(A);
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4476: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a, b) {
|
||||||
|
(a => {
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
})(b);
|
||||||
|
})("foo", "bar");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a, b) {
|
||||||
|
(a => {
|
||||||
|
console.log(arguments[0], a);
|
||||||
|
})(b);
|
||||||
|
})("foo", "bar");
|
||||||
|
}
|
||||||
|
expect_stdout: "foo bar"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
@@ -461,3 +461,17 @@ issue_3949_2: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "100"
|
expect_stdout: "100"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4521: {
|
||||||
|
options = {
|
||||||
|
assignments: true,
|
||||||
|
dead_code: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = (a = 42 | a) ? console.log(a) : 0;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = (a |= 42) ? console.log(a) : 0;
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|||||||
1066
test/compress/awaits.js
Normal file
1066
test/compress/awaits.js
Normal file
File diff suppressed because it is too large
Load Diff
62
test/compress/bigint.js
Normal file
62
test/compress/bigint.js
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
arithmetic: {
|
||||||
|
input: {
|
||||||
|
console.log(((1n + 0x2n) * (0o3n - -4n)) >> (5n - 6n));
|
||||||
|
}
|
||||||
|
expect_exact: "console.log((1n+0x2n)*(0o3n- -4n)>>5n-6n);"
|
||||||
|
expect_stdout: "42n"
|
||||||
|
node_version: ">=10"
|
||||||
|
}
|
||||||
|
|
||||||
|
minus_dot: {
|
||||||
|
input: {
|
||||||
|
console.log(typeof -42n.toString(), typeof (-42n).toString());
|
||||||
|
}
|
||||||
|
expect_exact: "console.log(typeof-42n.toString(),typeof(-42n).toString());"
|
||||||
|
expect_stdout: "number string"
|
||||||
|
node_version: ">=10"
|
||||||
|
}
|
||||||
|
|
||||||
|
evaluate: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log((0xDEAD_BEEFn).toString(16));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(0xdeadbeefn.toString(16));
|
||||||
|
}
|
||||||
|
expect_stdout: "deadbeef"
|
||||||
|
node_version: ">=10"
|
||||||
|
}
|
||||||
|
|
||||||
|
Number: {
|
||||||
|
options = {
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(Number(-0xfeed_dead_beef_badn));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(+("" + -0xfeed_dead_beef_badn));
|
||||||
|
}
|
||||||
|
expect_stdout: "-1148098955808013200"
|
||||||
|
node_version: ">=10"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4590: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
A = 1;
|
||||||
|
0n || console.log("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
A = 1;
|
||||||
|
0n || console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=10"
|
||||||
|
}
|
||||||
@@ -153,3 +153,31 @@ issue_3690: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4374: {
|
||||||
|
options = {
|
||||||
|
booleans: true,
|
||||||
|
conditionals: true,
|
||||||
|
if_return: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
console.log(f());
|
||||||
|
function f(a) {
|
||||||
|
if (null) return 0;
|
||||||
|
if (a) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
console.log(function(a) {
|
||||||
|
return !null && a ? 1 : 0;
|
||||||
|
}());
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "0"
|
||||||
|
}
|
||||||
|
|||||||
@@ -3145,8 +3145,8 @@ issue_2313_2: {
|
|||||||
var c = 0;
|
var c = 0;
|
||||||
!function a() {
|
!function a() {
|
||||||
a && c++;
|
a && c++;
|
||||||
var a = 0;
|
var a;
|
||||||
a && c++;
|
(a = 0) && c++;
|
||||||
}();
|
}();
|
||||||
console.log(c);
|
console.log(c);
|
||||||
}
|
}
|
||||||
@@ -4273,8 +4273,8 @@ issue_2436_14: {
|
|||||||
var b = {};
|
var b = {};
|
||||||
(function() {
|
(function() {
|
||||||
a && function(c, d) {
|
a && function(c, d) {
|
||||||
console.log(c, d);
|
console.log(b, d);
|
||||||
}(b, a);
|
}(0, a);
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
@@ -5502,8 +5502,7 @@ collapse_rhs_lhs_2: {
|
|||||||
expect: {
|
expect: {
|
||||||
var b = 1;
|
var b = 1;
|
||||||
(function f(f) {
|
(function f(f) {
|
||||||
f = b;
|
b[b] = 0;
|
||||||
f[b] = 0;
|
|
||||||
})();
|
})();
|
||||||
console.log("PASS");
|
console.log("PASS");
|
||||||
}
|
}
|
||||||
@@ -5609,6 +5608,7 @@ collapse_rhs_array: {
|
|||||||
collapse_rhs_boolean_1: {
|
collapse_rhs_boolean_1: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a, b;
|
var a, b;
|
||||||
@@ -5634,6 +5634,7 @@ collapse_rhs_boolean_1: {
|
|||||||
collapse_rhs_boolean_2: {
|
collapse_rhs_boolean_2: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a;
|
var a;
|
||||||
@@ -5668,6 +5669,7 @@ collapse_rhs_boolean_3: {
|
|||||||
booleans: true,
|
booleans: true,
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
|
evaluate: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a, f, g, h, i, n, s, t, x, y;
|
var a, f, g, h, i, n, s, t, x, y;
|
||||||
@@ -5721,6 +5723,7 @@ collapse_rhs_function: {
|
|||||||
collapse_rhs_number: {
|
collapse_rhs_number: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a, b;
|
var a, b;
|
||||||
@@ -5800,6 +5803,7 @@ collapse_rhs_regexp: {
|
|||||||
collapse_rhs_string: {
|
collapse_rhs_string: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a, b;
|
var a, b;
|
||||||
@@ -5996,7 +6000,7 @@ issue_3215_1: {
|
|||||||
}());
|
}());
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log(typeof 42);
|
console.log("number");
|
||||||
}
|
}
|
||||||
expect_stdout: "number"
|
expect_stdout: "number"
|
||||||
}
|
}
|
||||||
@@ -8602,3 +8606,152 @@ issue_4248: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "1"
|
expect_stdout: "1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4430_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
switch (a = 1, arguments[0]) {
|
||||||
|
case 1:
|
||||||
|
return "PASS";
|
||||||
|
case 2:
|
||||||
|
return "FAIL";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(f(2));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
switch (a = 1, arguments[0]) {
|
||||||
|
case 1:
|
||||||
|
return "PASS";
|
||||||
|
case 2:
|
||||||
|
return "FAIL";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(f(2));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4430_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
switch (a = 0, arguments[0]) {
|
||||||
|
case 0:
|
||||||
|
return "PASS";
|
||||||
|
case 1:
|
||||||
|
return "FAIL";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(f(1));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
switch (arguments[a = 0]) {
|
||||||
|
case 0:
|
||||||
|
return "PASS";
|
||||||
|
case 1:
|
||||||
|
return "FAIL";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(f(1));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
collapse_and_assign: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var log = console.log;
|
||||||
|
var a = {
|
||||||
|
p: "PASS",
|
||||||
|
};
|
||||||
|
console && (a = a.p);
|
||||||
|
log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var log = console.log;
|
||||||
|
var a = {
|
||||||
|
p: "PASS",
|
||||||
|
};
|
||||||
|
log(a = console ? a.p : a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
collapse_or_assign: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var log = console.log;
|
||||||
|
var a = {
|
||||||
|
p: "PASS",
|
||||||
|
};
|
||||||
|
a.q || (a = a.p);
|
||||||
|
log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var log = console.log;
|
||||||
|
var a = {
|
||||||
|
p: "PASS",
|
||||||
|
};
|
||||||
|
log(a = !a.q ? a.p : a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4586_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 42;
|
||||||
|
(function f(b) {
|
||||||
|
var b = a;
|
||||||
|
if (b === arguments[0])
|
||||||
|
console.log("PASS");
|
||||||
|
})(console);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 42;
|
||||||
|
(function f(b) {
|
||||||
|
var b = a;
|
||||||
|
if (b === arguments[0])
|
||||||
|
console.log("PASS");
|
||||||
|
})(console);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4586_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 42;
|
||||||
|
(function f(b) {
|
||||||
|
b = a;
|
||||||
|
if (b === arguments[0])
|
||||||
|
console.log("PASS");
|
||||||
|
})(console);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 42;
|
||||||
|
(function f(b) {
|
||||||
|
if ((b = a) === arguments[0])
|
||||||
|
console.log("PASS");
|
||||||
|
})(console);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -658,6 +658,30 @@ legacy_scope: {
|
|||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hoist_vars: {
|
||||||
|
options = {
|
||||||
|
hoist_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
{
|
||||||
|
const a = "FAIL";
|
||||||
|
var b = 42;
|
||||||
|
}
|
||||||
|
var a = "PASS";
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var b;
|
||||||
|
{
|
||||||
|
const a = "FAIL";
|
||||||
|
b = 42;
|
||||||
|
}
|
||||||
|
var a = "PASS";
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
issue_4191: {
|
issue_4191: {
|
||||||
options = {
|
options = {
|
||||||
functions: true,
|
functions: true,
|
||||||
@@ -1347,3 +1371,66 @@ issue_4305_2: {
|
|||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4365_1: {
|
||||||
|
options = {
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
const arguments = 42;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
const arguments = 42;
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4365_2: {
|
||||||
|
options = {
|
||||||
|
toplevel: true,
|
||||||
|
varify: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
const arguments = 42;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
const arguments = 42;
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4527: {
|
||||||
|
mangle = {}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
try {
|
||||||
|
throw 1;
|
||||||
|
} catch (a) {
|
||||||
|
try {
|
||||||
|
const a = FAIL;
|
||||||
|
} finally {
|
||||||
|
if (!b)
|
||||||
|
return console.log("aaaa");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var b;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
try {
|
||||||
|
throw 1;
|
||||||
|
} catch (a) {
|
||||||
|
try {
|
||||||
|
const a = FAIL;
|
||||||
|
} finally {
|
||||||
|
if (!t)
|
||||||
|
return console.log("aaaa");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var t;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "aaaa"
|
||||||
|
}
|
||||||
|
|||||||
@@ -725,7 +725,7 @@ issue_2749: {
|
|||||||
expect: {
|
expect: {
|
||||||
var a = 2, c = "PASS";
|
var a = 2, c = "PASS";
|
||||||
while (a--)
|
while (a--)
|
||||||
b = void 0, b ? c = "FAIL" : b = 1;
|
b = void 0, b ? c = "FAIL" : 1;
|
||||||
var b;
|
var b;
|
||||||
console.log(c);
|
console.log(c);
|
||||||
}
|
}
|
||||||
@@ -1375,3 +1375,45 @@ issue_4051: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4366: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
return "PASS";
|
||||||
|
({
|
||||||
|
p: 42,
|
||||||
|
get p() {},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
return "PASS";
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4570: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
inline: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = function(b) {
|
||||||
|
return a += b;
|
||||||
|
}() ? 0 : a;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = (a += void 0) ? 0 : a;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "NaN"
|
||||||
|
}
|
||||||
|
|||||||
1663
test/compress/default-values.js
Normal file
1663
test/compress/default-values.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -40,7 +40,7 @@ redefine_arguments_2: {
|
|||||||
|
|
||||||
redefine_arguments_3: {
|
redefine_arguments_3: {
|
||||||
options = {
|
options = {
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -188,7 +188,7 @@ funarg_side_effects_1: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
try {
|
try {
|
||||||
(function({}) {})();
|
[ {} ] = [];
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("PASS");
|
console.log("PASS");
|
||||||
}
|
}
|
||||||
@@ -259,7 +259,7 @@ funarg_side_effects_3: {
|
|||||||
|
|
||||||
funarg_unused_1: {
|
funarg_unused_1: {
|
||||||
options = {
|
options = {
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -318,7 +318,7 @@ funarg_unused_3: {
|
|||||||
|
|
||||||
funarg_unused_4: {
|
funarg_unused_4: {
|
||||||
options = {
|
options = {
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
pure_getters: "strict",
|
pure_getters: "strict",
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
@@ -384,7 +384,7 @@ funarg_unused_6_inline: {
|
|||||||
|
|
||||||
funarg_unused_6_keep_fargs: {
|
funarg_unused_6_keep_fargs: {
|
||||||
options = {
|
options = {
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -426,7 +426,7 @@ funarg_collapse_vars_1: {
|
|||||||
funarg_collapse_vars_2: {
|
funarg_collapse_vars_2: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -505,7 +505,7 @@ funarg_reduce_vars_1: {
|
|||||||
funarg_reduce_vars_2: {
|
funarg_reduce_vars_2: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
pure_getters: "strict",
|
pure_getters: "strict",
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unsafe: true,
|
unsafe: true,
|
||||||
@@ -682,7 +682,7 @@ funarg_inline: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
try {
|
try {
|
||||||
(function({}) {})();
|
[ {} ] = [];
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("PASS");
|
console.log("PASS");
|
||||||
}
|
}
|
||||||
@@ -691,6 +691,28 @@ funarg_inline: {
|
|||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
process_boolean_returns: {
|
||||||
|
options = {
|
||||||
|
booleans: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function({ length }) {
|
||||||
|
return length ? "FAIL" : "PASS";
|
||||||
|
}(function() {
|
||||||
|
return 42;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function({ length }) {
|
||||||
|
return length ? "FAIL" : "PASS";
|
||||||
|
}(function() {
|
||||||
|
return 42;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
simple_const: {
|
simple_const: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
@@ -750,6 +772,46 @@ simple_var: {
|
|||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
drop_catch: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {} catch ({
|
||||||
|
[console.log("FAIL")]: e,
|
||||||
|
}) {} finally {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_catch_var: {
|
||||||
|
options = {
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
throw new Error("PASS");
|
||||||
|
} catch ({ name, message }) {
|
||||||
|
console.log(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
throw new Error("PASS");
|
||||||
|
} catch ({ message }) {
|
||||||
|
console.log(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
collapse_vars_1: {
|
collapse_vars_1: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
@@ -1061,7 +1123,7 @@ join_vars: {
|
|||||||
|
|
||||||
keep_fargs: {
|
keep_fargs: {
|
||||||
options = {
|
options = {
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -1296,6 +1358,24 @@ fn_name_unused: {
|
|||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hoist_vars: {
|
||||||
|
options = {
|
||||||
|
hoist_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS";
|
||||||
|
var [ b ] = [ 42 ];
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "PASS";
|
||||||
|
var [ b ] = [ 42 ];
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS 42"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
issue_4280: {
|
issue_4280: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
@@ -1638,10 +1718,14 @@ issue_4312: {
|
|||||||
expect: {
|
expect: {
|
||||||
var a;
|
var a;
|
||||||
b = "PASS",
|
b = "PASS",
|
||||||
(function({
|
c = "FAIL",
|
||||||
[a = b]: d,
|
[
|
||||||
}){})((c = "FAIL") && c);
|
{
|
||||||
var b, c;
|
[a = b]: d,
|
||||||
|
},
|
||||||
|
] = [ c && c ],
|
||||||
|
void 0;
|
||||||
|
var b, c, d;
|
||||||
console.log(a);
|
console.log(a);
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
@@ -1703,9 +1787,7 @@ issue_4319: {
|
|||||||
function f(a) {
|
function f(a) {
|
||||||
while (!a);
|
while (!a);
|
||||||
}
|
}
|
||||||
console.log(function({}) {
|
console.log(([ {} ] = [ 0 ], f(console)));
|
||||||
return f(console);
|
|
||||||
}(0));
|
|
||||||
}
|
}
|
||||||
expect_stdout: "undefined"
|
expect_stdout: "undefined"
|
||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
@@ -1714,7 +1796,7 @@ issue_4319: {
|
|||||||
issue_4321: {
|
issue_4321: {
|
||||||
options = {
|
options = {
|
||||||
inline: true,
|
inline: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
try {
|
try {
|
||||||
@@ -1729,11 +1811,9 @@ issue_4321: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
try {
|
try {
|
||||||
console.log(function({}) {
|
console.log(([ {} ] = [], function() {
|
||||||
return function() {
|
while (!console);
|
||||||
while (!console);
|
}()));
|
||||||
}();
|
|
||||||
}());
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("PASS");
|
console.log("PASS");
|
||||||
}
|
}
|
||||||
@@ -1764,11 +1844,15 @@ issue_4323: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a = 0;
|
var a = 0;
|
||||||
(function({
|
[
|
||||||
[function a() {
|
{
|
||||||
console.log(typeof a);
|
[function a() {
|
||||||
}()]: d,
|
console.log(typeof a);
|
||||||
}) {})(0);
|
}()]: d,
|
||||||
|
},
|
||||||
|
] = [ 0 ],
|
||||||
|
void 0;
|
||||||
|
var d;
|
||||||
e = 1,
|
e = 1,
|
||||||
console.log,
|
console.log,
|
||||||
void e.p;
|
void e.p;
|
||||||
@@ -1777,3 +1861,656 @@ issue_4323: {
|
|||||||
expect_stdout: "function"
|
expect_stdout: "function"
|
||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4355: {
|
||||||
|
options = {
|
||||||
|
loops: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
(function({
|
||||||
|
[function() {
|
||||||
|
for (a in "foo");
|
||||||
|
}()]: b,
|
||||||
|
}) {
|
||||||
|
var a;
|
||||||
|
})(0);
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
(function({
|
||||||
|
[function() {
|
||||||
|
for (a in "foo");
|
||||||
|
}()]: b,
|
||||||
|
}) {})(0);
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "2"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4372_1: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "FAIL";
|
||||||
|
a += {
|
||||||
|
[console.log(a)]: a,
|
||||||
|
} = a = "PASS";
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "FAIL";
|
||||||
|
a += {
|
||||||
|
[console.log(a)]: a,
|
||||||
|
} = a = "PASS";
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4372_2: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
[ a ] = a = [ "PASS", "FAIL" ];
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
[ a ] = [ "PASS", "FAIL" ];
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4383: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a) {
|
||||||
|
[ a[0] ] = [];
|
||||||
|
return a.length;
|
||||||
|
}([]));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a) {
|
||||||
|
[ a[0] ] = [];
|
||||||
|
return a.length;
|
||||||
|
}([]));
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4386: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f({}) {
|
||||||
|
return arguments[0];
|
||||||
|
}
|
||||||
|
console.log(f("PASS"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f({}) {
|
||||||
|
return arguments[0];
|
||||||
|
}
|
||||||
|
console.log(f("PASS"));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4395: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a, {}) {
|
||||||
|
a = "FAIL";
|
||||||
|
return arguments[0];
|
||||||
|
}("PASS", 42));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a, {}) {
|
||||||
|
a = "FAIL";
|
||||||
|
return arguments[0];
|
||||||
|
}("PASS", 42));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4399: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function({
|
||||||
|
[arguments[1]]: a,
|
||||||
|
}, b) {
|
||||||
|
return a;
|
||||||
|
}([ "PASS" ], 0));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function({
|
||||||
|
[arguments[1]]: a,
|
||||||
|
}, b) {
|
||||||
|
return a;
|
||||||
|
}([ "PASS" ], 0));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4420: {
|
||||||
|
options = {
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
var a = 1;
|
||||||
|
try {
|
||||||
|
throw [ "FAIL", "PASS" ];
|
||||||
|
} catch ({
|
||||||
|
[a]: b,
|
||||||
|
}) {
|
||||||
|
let a = 0;
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
var a = 1;
|
||||||
|
try {
|
||||||
|
throw [ "FAIL", "PASS" ];
|
||||||
|
} catch ({
|
||||||
|
[a]: b,
|
||||||
|
}) {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4425: {
|
||||||
|
rename = true
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
console.log(function() {
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch ({
|
||||||
|
[a]: a,
|
||||||
|
}) {}
|
||||||
|
return "FAIL";
|
||||||
|
} catch (e) {
|
||||||
|
return "PASS";
|
||||||
|
}
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
console.log(function() {
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch ({
|
||||||
|
[b]: b,
|
||||||
|
}) {}
|
||||||
|
return "FAIL";
|
||||||
|
} catch (c) {
|
||||||
|
return "PASS";
|
||||||
|
}
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4436_Infinity: {
|
||||||
|
options = {
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function({
|
||||||
|
[delete Infinity]: a,
|
||||||
|
}) {
|
||||||
|
var Infinity;
|
||||||
|
return a;
|
||||||
|
}({
|
||||||
|
true: "FAIL",
|
||||||
|
false: "PASS",
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function({
|
||||||
|
[delete Infinity]: a,
|
||||||
|
}) {
|
||||||
|
return a;
|
||||||
|
}({
|
||||||
|
true: "FAIL",
|
||||||
|
false: "PASS",
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4436_NaN: {
|
||||||
|
options = {
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function({
|
||||||
|
[delete NaN]: a,
|
||||||
|
}) {
|
||||||
|
var NaN;
|
||||||
|
return a;
|
||||||
|
}({
|
||||||
|
true: "FAIL",
|
||||||
|
false: "PASS",
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function({
|
||||||
|
[delete NaN]: a,
|
||||||
|
}) {
|
||||||
|
return a;
|
||||||
|
}({
|
||||||
|
true: "FAIL",
|
||||||
|
false: "PASS",
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4436_undefined: {
|
||||||
|
options = {
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function({
|
||||||
|
[delete undefined]: a,
|
||||||
|
}) {
|
||||||
|
var undefined;
|
||||||
|
return a;
|
||||||
|
}({
|
||||||
|
true: "FAIL",
|
||||||
|
false: "PASS",
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function({
|
||||||
|
[delete undefined]: a,
|
||||||
|
}) {
|
||||||
|
return a;
|
||||||
|
}({
|
||||||
|
true: "FAIL",
|
||||||
|
false: "PASS",
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4446: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
a = "PASS";
|
||||||
|
var a = [ a[0] ] = [ a ];
|
||||||
|
console.log(a[0]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
a = "PASS";
|
||||||
|
var a = [ a[0] ] = [ a ];
|
||||||
|
console.log(a[0]);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4456: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
set p(v) {
|
||||||
|
console.log(v);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
[ function() {
|
||||||
|
try {
|
||||||
|
return o;
|
||||||
|
} catch ({}) {}
|
||||||
|
}().p ] = [ "PASS" ];
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
set p(v) {
|
||||||
|
console.log(v);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
[ function() {
|
||||||
|
try {
|
||||||
|
return o;
|
||||||
|
} catch ({}) {}
|
||||||
|
}().p ] = [ "PASS" ];
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4485_1: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function([]) {
|
||||||
|
var arguments;
|
||||||
|
try {
|
||||||
|
arguments.length;
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
})([]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function([]) {
|
||||||
|
var arguments;
|
||||||
|
try {
|
||||||
|
arguments.length;
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
})([]);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4485_2: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function([]) {
|
||||||
|
var arguments = null;
|
||||||
|
try {
|
||||||
|
arguments.length;
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
})([]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function([]) {
|
||||||
|
var arguments = null;
|
||||||
|
try {
|
||||||
|
arguments.length;
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
})([]);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4485_3: {
|
||||||
|
options = {
|
||||||
|
keep_fargs: false,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function([]) {
|
||||||
|
var arguments;
|
||||||
|
try {
|
||||||
|
arguments.length;
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
})([]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function([]) {
|
||||||
|
var arguments;
|
||||||
|
try {
|
||||||
|
arguments.length;
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
})([]);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4500: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
keep_fnames: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = function f(b) {
|
||||||
|
return [ b ] = [], b;
|
||||||
|
}("FAIL");
|
||||||
|
console.log(a || "PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = function f(b) {
|
||||||
|
return [ b ] = [], b;
|
||||||
|
}("FAIL");
|
||||||
|
console.log(a || "PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4504: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
merge_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
A = "FAIL";
|
||||||
|
(function f(a) {
|
||||||
|
({
|
||||||
|
[console.log(a)]: 0[(b => console + b)(A)]
|
||||||
|
} = 0);
|
||||||
|
})("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
A = "FAIL";
|
||||||
|
(function f(a) {
|
||||||
|
({
|
||||||
|
[console.log(a)]: 0[b = A, console + b]
|
||||||
|
} = 0);
|
||||||
|
var b;
|
||||||
|
})("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4508: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
for (var i = 0; i < 2; i++)
|
||||||
|
(function f([ a ]) {
|
||||||
|
var a = console.log(a) && b, b = null;
|
||||||
|
})([ "PASS" ]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
for (var i = 0; i < 2; i++)
|
||||||
|
[ [ a ] ] = [ [ "PASS" ] ],
|
||||||
|
b = void 0,
|
||||||
|
a = console.log(a) && b,
|
||||||
|
b = null,
|
||||||
|
void 0;
|
||||||
|
var a, b;
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"PASS",
|
||||||
|
"PASS",
|
||||||
|
]
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4512: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function([ a, b = a ]) {}([]));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function([ a, b = a ]) {}([]));
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4519_1: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
(function() {
|
||||||
|
var [ arguments ] = [];
|
||||||
|
arguments[0];
|
||||||
|
})();
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
(function() {
|
||||||
|
var [ arguments ] = [];
|
||||||
|
arguments[0];
|
||||||
|
})();
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4519_2: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
(function() {
|
||||||
|
var [ arguments ] = [];
|
||||||
|
arguments[0];
|
||||||
|
})();
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
(function() {
|
||||||
|
var [ arguments ] = [];
|
||||||
|
arguments[0];
|
||||||
|
})();
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4554: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
A = "PASS";
|
||||||
|
var a = "FAIL";
|
||||||
|
try {
|
||||||
|
(function({}, b) {
|
||||||
|
return b;
|
||||||
|
})(void 0, a = A);
|
||||||
|
} catch (e) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
A = "PASS";
|
||||||
|
var a = "FAIL";
|
||||||
|
try {
|
||||||
|
(function({}, b) {
|
||||||
|
return b;
|
||||||
|
})(void 0, a = A);
|
||||||
|
} catch (e) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4584: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
(function f({
|
||||||
|
[console.log(a = "FAIL")]: a,
|
||||||
|
}) {})(0);
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
(function f({
|
||||||
|
[console.log(a = "FAIL")]: a,
|
||||||
|
}) {})(0);
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,15 +4,16 @@ unused_funarg_1: {
|
|||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f(a, b, c, d, e) {
|
console.log(function f(a, b, c, d, e) {
|
||||||
return a + b;
|
return a + b;
|
||||||
}
|
}(14, 28));
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f(a, b) {
|
console.log(function(a, b) {
|
||||||
return a + b;
|
return a + b;
|
||||||
}
|
}(14, 28));
|
||||||
}
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
}
|
}
|
||||||
|
|
||||||
unused_funarg_2: {
|
unused_funarg_2: {
|
||||||
@@ -21,15 +22,16 @@ unused_funarg_2: {
|
|||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f(a, b, c, d, e) {
|
console.log(function f(a, b, c, d, e) {
|
||||||
return a + c;
|
return a + c;
|
||||||
}
|
}(14, 21, 28));
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f(a, b, c) {
|
console.log(function(a, c) {
|
||||||
return a + c;
|
return a + c;
|
||||||
}
|
}(14, 28));
|
||||||
}
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
}
|
}
|
||||||
|
|
||||||
unused_nested_function: {
|
unused_nested_function: {
|
||||||
@@ -357,37 +359,6 @@ drop_toplevel_vars: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
drop_toplevel_vars_fargs: {
|
|
||||||
options = {
|
|
||||||
keep_fargs: false,
|
|
||||||
toplevel: "vars",
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var a, b = 1, c = g;
|
|
||||||
function f(d) {
|
|
||||||
return function() {
|
|
||||||
c = 2;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
a = 2;
|
|
||||||
function g() {}
|
|
||||||
function h() {}
|
|
||||||
console.log(b = 3);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function f() {
|
|
||||||
return function() {
|
|
||||||
2;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
2;
|
|
||||||
function g() {}
|
|
||||||
function h() {}
|
|
||||||
console.log(3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
drop_toplevel_all: {
|
drop_toplevel_all: {
|
||||||
options = {
|
options = {
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
@@ -625,13 +596,14 @@ drop_fargs: {
|
|||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f(a) {
|
console.log(function f(a) {
|
||||||
var b = a;
|
var b = a;
|
||||||
}
|
}());
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f() {}
|
console.log(function() {}());
|
||||||
}
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
}
|
}
|
||||||
|
|
||||||
drop_fnames: {
|
drop_fnames: {
|
||||||
@@ -2027,7 +1999,7 @@ issue_3192_1: {
|
|||||||
|
|
||||||
issue_3192_2: {
|
issue_3192_2: {
|
||||||
options = {
|
options = {
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -2166,6 +2138,7 @@ issue_3497: {
|
|||||||
issue_3515_1: {
|
issue_3515_1: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
@@ -2217,6 +2190,7 @@ issue_3515_2: {
|
|||||||
issue_3515_3: {
|
issue_3515_3: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -2284,6 +2258,7 @@ function_assign: {
|
|||||||
issue_3598: {
|
issue_3598: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
@@ -2435,7 +2410,7 @@ issue_3673: {
|
|||||||
|
|
||||||
issue_3746: {
|
issue_3746: {
|
||||||
options = {
|
options = {
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
@@ -2697,8 +2672,7 @@ issue_3956: {
|
|||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var c, d;
|
var d;
|
||||||
c += 0,
|
|
||||||
console.log(NaN),
|
console.log(NaN),
|
||||||
d = 1 ^ console.log(1),
|
d = 1 ^ console.log(1),
|
||||||
console.log(d);
|
console.log(d);
|
||||||
@@ -2713,7 +2687,7 @@ issue_3956: {
|
|||||||
issue_3962_1: {
|
issue_3962_1: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -2731,13 +2705,13 @@ issue_3962_1: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a = 0;
|
var a = 0;
|
||||||
a = (function(c) {
|
(function(c) {
|
||||||
do {
|
do {
|
||||||
console;
|
console;
|
||||||
0..toString();
|
0..toString();
|
||||||
} while (0);
|
} while (0);
|
||||||
if (c) console.log("PASS");
|
if (c) console.log("PASS");
|
||||||
}(1), 0);
|
})(1);
|
||||||
void 0;
|
void 0;
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
@@ -2745,7 +2719,7 @@ issue_3962_1: {
|
|||||||
|
|
||||||
issue_3962_2: {
|
issue_3962_2: {
|
||||||
options = {
|
options = {
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
@@ -2764,13 +2738,13 @@ issue_3962_2: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a = 0;
|
var a = 0;
|
||||||
a = (function(c) {
|
(function(c) {
|
||||||
do {
|
do {
|
||||||
console;
|
console;
|
||||||
0..toString();
|
0..toString();
|
||||||
} while (0);
|
} while (0);
|
||||||
if (c) console.log("PASS");
|
if (c) console.log("PASS");
|
||||||
}(1), 0);
|
})(1);
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
@@ -2827,7 +2801,9 @@ issue_4017: {
|
|||||||
var a = 0;
|
var a = 0;
|
||||||
console.log(function() {
|
console.log(function() {
|
||||||
c &= 0;
|
c &= 0;
|
||||||
var c = (a++, A = a, 0);
|
var c;
|
||||||
|
a++,
|
||||||
|
A = a;
|
||||||
}());
|
}());
|
||||||
}
|
}
|
||||||
expect_stdout: "undefined"
|
expect_stdout: "undefined"
|
||||||
@@ -2948,7 +2924,7 @@ issue_4133: {
|
|||||||
|
|
||||||
issue_4144: {
|
issue_4144: {
|
||||||
options = {
|
options = {
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
@@ -3112,3 +3088,166 @@ issue_4235: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "undefined"
|
expect_stdout: "undefined"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4404: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
arguments[0] = "PASS";
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
f("FAIL");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
arguments[0] = "PASS";
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
f("FAIL");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4413: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function f(arguments) {
|
||||||
|
var arguments = function() {};
|
||||||
|
return arguments.length;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(arguments) {
|
||||||
|
return function() {}.length;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4464_1: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
var a = function() {};
|
||||||
|
return [ arguments, a ];
|
||||||
|
}
|
||||||
|
console.log(typeof f()[1]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
a = function() {};
|
||||||
|
return [ arguments, a ];
|
||||||
|
}
|
||||||
|
console.log(typeof f()[1]);
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4464_2: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
var a = function() {};
|
||||||
|
return [ arguments, a ];
|
||||||
|
}
|
||||||
|
console.log(typeof f(42)[0][0]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
a = function() {};
|
||||||
|
return [ arguments, a ];
|
||||||
|
}
|
||||||
|
console.log(typeof f(42)[0][0]);
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4464_3: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function a(a) {
|
||||||
|
var a = function() {};
|
||||||
|
return [ arguments[0], a ];
|
||||||
|
})(42).forEach(function(b) {
|
||||||
|
console.log(typeof b);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a) {
|
||||||
|
a = function() {};
|
||||||
|
return [ arguments[0], a ];
|
||||||
|
})(42).forEach(function(b) {
|
||||||
|
console.log(typeof b);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"function",
|
||||||
|
"function",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4558_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
pure_getters: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0;
|
||||||
|
var b = 1, b = c >>>= a;
|
||||||
|
var c = 0;
|
||||||
|
b && 0[a++],
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0;
|
||||||
|
var b = c >>>= a;
|
||||||
|
var c;
|
||||||
|
b && a++,
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4558_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
ie8: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
var a = 1;
|
||||||
|
var b = (a = NaN) || (console.log("PASS"), 2);
|
||||||
|
return a;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
var a;
|
||||||
|
(a = NaN) || console.log("PASS");
|
||||||
|
return a;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -3074,3 +3074,104 @@ issue_4271: {
|
|||||||
"PASS",
|
"PASS",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4393: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function f(a) {
|
||||||
|
a = "PASS";
|
||||||
|
console.log(arguments[0]);
|
||||||
|
})("FAIL");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function f(a) {
|
||||||
|
a = "PASS";
|
||||||
|
console.log(arguments[0]);
|
||||||
|
})("FAIL");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4422: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function f(a) {
|
||||||
|
a = "FAIL 1";
|
||||||
|
arguments[0] = "PASS";
|
||||||
|
return a;
|
||||||
|
}("FAIL 2"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a) {
|
||||||
|
a = "FAIL 1";
|
||||||
|
arguments[0] = "PASS";
|
||||||
|
return a;
|
||||||
|
}("FAIL 2"));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4480: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = function f(b) {
|
||||||
|
b = "FAIL";
|
||||||
|
arguments[0] = "PASS";
|
||||||
|
var arguments = 0;
|
||||||
|
console.log(b);
|
||||||
|
}(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = function(b) {
|
||||||
|
b = "FAIL";
|
||||||
|
arguments[0] = "PASS";
|
||||||
|
var arguments = 0;
|
||||||
|
console.log(b);
|
||||||
|
}(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4552: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
keep_fnames: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = function f(b) {
|
||||||
|
return function() {
|
||||||
|
b++;
|
||||||
|
try {
|
||||||
|
return b;
|
||||||
|
} catch (e) {}
|
||||||
|
}();
|
||||||
|
}();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = function f(b) {
|
||||||
|
return function() {
|
||||||
|
b++;
|
||||||
|
try {
|
||||||
|
return b;
|
||||||
|
} catch (e) {}
|
||||||
|
}();
|
||||||
|
}();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "NaN"
|
||||||
|
}
|
||||||
|
|||||||
58
test/compress/exponentiation.js
Normal file
58
test/compress/exponentiation.js
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
precedence_1: {
|
||||||
|
input: {
|
||||||
|
console.log(-4 ** 3 ** 2);
|
||||||
|
}
|
||||||
|
expect_exact: "console.log((-4)**3**2);"
|
||||||
|
expect_stdout: "-262144"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
precedence_2: {
|
||||||
|
input: {
|
||||||
|
console.log(-4 ** (3 ** 2));
|
||||||
|
}
|
||||||
|
expect_exact: "console.log((-4)**3**2);"
|
||||||
|
expect_stdout: "-262144"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
precedence_3: {
|
||||||
|
input: {
|
||||||
|
console.log(-(4 ** 3) ** 2);
|
||||||
|
}
|
||||||
|
expect_exact: "console.log((-(4**3))**2);"
|
||||||
|
expect_stdout: "4096"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
precedence_4: {
|
||||||
|
input: {
|
||||||
|
console.log((-4 ** 3) ** 2);
|
||||||
|
}
|
||||||
|
expect_exact: "console.log(((-4)**3)**2);"
|
||||||
|
expect_stdout: "4096"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
await: {
|
||||||
|
input: {
|
||||||
|
(async a => a * await a ** ++a % a)(2).then(console.log);
|
||||||
|
}
|
||||||
|
expect_exact: "(async a=>a*(await a)**++a%a)(2).then(console.log);"
|
||||||
|
expect_stdout: "1"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
evaluate: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(1 + 2 ** 3 - 4);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(5);
|
||||||
|
}
|
||||||
|
expect_stdout: "5"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
@@ -229,7 +229,7 @@ issue_203: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var m = {};
|
var m = {};
|
||||||
var fn = Function("n,o", "o.exports=42");
|
var fn = Function("n,o,t", "o.exports=42");
|
||||||
fn(null, m, m.exports);
|
fn(null, m, m.exports);
|
||||||
console.log(m.exports);
|
console.log(m.exports);
|
||||||
}
|
}
|
||||||
@@ -2175,7 +2175,7 @@ issue_3016_3: {
|
|||||||
expect: {
|
expect: {
|
||||||
var b = 1;
|
var b = 1;
|
||||||
do {
|
do {
|
||||||
console.log((a = void 0, a ? "FAIL" : a = "PASS"));
|
console.log((a = void 0, a ? "FAIL" : "PASS"));
|
||||||
} while (b--);
|
} while (b--);
|
||||||
var a;
|
var a;
|
||||||
}
|
}
|
||||||
@@ -2208,7 +2208,7 @@ issue_3016_3_ie8: {
|
|||||||
expect: {
|
expect: {
|
||||||
var b = 1;
|
var b = 1;
|
||||||
do {
|
do {
|
||||||
console.log((a = void 0, a ? "FAIL" : a = "PASS"));
|
console.log((a = void 0, a ? "FAIL" : "PASS"));
|
||||||
} while (b--);
|
} while (b--);
|
||||||
var a;
|
var a;
|
||||||
}
|
}
|
||||||
@@ -4230,7 +4230,7 @@ substitute: {
|
|||||||
substitute_add_farg: {
|
substitute_add_farg: {
|
||||||
options = {
|
options = {
|
||||||
inline: true,
|
inline: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f(g) {
|
function f(g) {
|
||||||
@@ -4411,7 +4411,9 @@ substitute_drop_farg: {
|
|||||||
return f;
|
return f;
|
||||||
},
|
},
|
||||||
function() {
|
function() {
|
||||||
return f;
|
return function(d, e) {
|
||||||
|
return f(d, e);
|
||||||
|
};
|
||||||
},
|
},
|
||||||
].forEach(function(g) {
|
].forEach(function(g) {
|
||||||
console.log(g()(o), g().call(o, o));
|
console.log(g()(o), g().call(o, o));
|
||||||
@@ -4594,7 +4596,7 @@ substitute_use_strict: {
|
|||||||
issue_3833: {
|
issue_3833: {
|
||||||
options = {
|
options = {
|
||||||
inline: true,
|
inline: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -4751,7 +4753,7 @@ issue_4006: {
|
|||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
inline: true,
|
inline: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
sequences: true,
|
sequences: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
@@ -5132,8 +5134,8 @@ issue_4259: {
|
|||||||
console.log(typeof a);
|
console.log(typeof a);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function a() {
|
var a = function b() {
|
||||||
for (a in a);
|
for (b in b);
|
||||||
}
|
}
|
||||||
a();
|
a();
|
||||||
console.log(typeof a);
|
console.log(typeof a);
|
||||||
@@ -5213,3 +5215,71 @@ issue_4265: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "undefined"
|
expect_stdout: "undefined"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trailing_comma: {
|
||||||
|
input: {
|
||||||
|
new function(a, b,) {
|
||||||
|
console.log(b, a,);
|
||||||
|
}(42, "PASS",);
|
||||||
|
}
|
||||||
|
expect_exact: 'new function(a,b){console.log(b,a)}(42,"PASS");'
|
||||||
|
expect_stdout: "PASS 42"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4451: {
|
||||||
|
options = {
|
||||||
|
functions: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = function f() {
|
||||||
|
for (f in "foo")
|
||||||
|
return f;
|
||||||
|
};
|
||||||
|
while (console.log(typeof a()));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = function f() {
|
||||||
|
for (f in "foo")
|
||||||
|
return f;
|
||||||
|
};
|
||||||
|
while (console.log(typeof a()));
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4471: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
f(f());
|
||||||
|
function f() {
|
||||||
|
return g();
|
||||||
|
}
|
||||||
|
function g() {
|
||||||
|
{
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
f(g());
|
||||||
|
function f() {
|
||||||
|
return g();
|
||||||
|
}
|
||||||
|
function g() {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"PASS",
|
||||||
|
"PASS",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
@@ -89,6 +89,31 @@ sequences_funs: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
catch_var: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
hoist_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS";
|
||||||
|
try {
|
||||||
|
a;
|
||||||
|
} catch (a) {
|
||||||
|
var a = 0;
|
||||||
|
a;
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "PASS";
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
issue_2295: {
|
issue_2295: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
@@ -109,3 +134,76 @@ issue_2295: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4487: {
|
||||||
|
options = {
|
||||||
|
functions: true,
|
||||||
|
hoist_vars: true,
|
||||||
|
keep_fnames: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = function f() {
|
||||||
|
var f = console.log(typeof f);
|
||||||
|
};
|
||||||
|
var b = a();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function a() {
|
||||||
|
var a = console.log(typeof a);
|
||||||
|
}
|
||||||
|
a();
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4489: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
hoist_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
A = 0;
|
||||||
|
var o = !0 || null;
|
||||||
|
for (var k in o);
|
||||||
|
console.log(k);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!(A = 0);
|
||||||
|
for (var k in true);
|
||||||
|
console.log(k);
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4517: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
hoist_vars: true,
|
||||||
|
join_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
var a = 2;
|
||||||
|
A = a;
|
||||||
|
var b = typeof !1;
|
||||||
|
return A + b;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
var a = 2;
|
||||||
|
A = a;
|
||||||
|
return A + typeof !1;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "2boolean"
|
||||||
|
}
|
||||||
|
|||||||
@@ -588,7 +588,6 @@ issue_3197_1: {
|
|||||||
ie8: false,
|
ie8: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var window = {};
|
|
||||||
!function() {
|
!function() {
|
||||||
function Foo() {
|
function Foo() {
|
||||||
console.log(this instanceof Foo);
|
console.log(this instanceof Foo);
|
||||||
@@ -598,7 +597,6 @@ issue_3197_1: {
|
|||||||
new window.Foo();
|
new window.Foo();
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var window = {};
|
|
||||||
window.Foo = function o() {
|
window.Foo = function o() {
|
||||||
console.log(this instanceof o);
|
console.log(this instanceof o);
|
||||||
};
|
};
|
||||||
@@ -619,7 +617,6 @@ issue_3197_1_ie8: {
|
|||||||
ie8: true,
|
ie8: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var window = {};
|
|
||||||
!function() {
|
!function() {
|
||||||
function Foo() {
|
function Foo() {
|
||||||
console.log(this instanceof Foo);
|
console.log(this instanceof Foo);
|
||||||
@@ -629,7 +626,6 @@ issue_3197_1_ie8: {
|
|||||||
new window.Foo();
|
new window.Foo();
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var window = {};
|
|
||||||
window.Foo = function Foo() {
|
window.Foo = function Foo() {
|
||||||
console.log(this instanceof Foo);
|
console.log(this instanceof Foo);
|
||||||
};
|
};
|
||||||
@@ -2904,3 +2900,22 @@ issue_4250: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "0"
|
expect_stdout: "0"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4568: {
|
||||||
|
options = {
|
||||||
|
ie8: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(typeof f, function(a) {
|
||||||
|
return a.length;
|
||||||
|
}([ function f() {} ]));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(typeof f, function(a) {
|
||||||
|
return a.length;
|
||||||
|
}([ function f() {} ]));
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined 1"
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ issue_269_1: {
|
|||||||
expect: {
|
expect: {
|
||||||
var x = {};
|
var x = {};
|
||||||
console.log(
|
console.log(
|
||||||
x + "", +x, !!x,
|
"" + x, +("" + x), !!x,
|
||||||
"", 0, false
|
"", 0, false
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,42 +63,81 @@ eval_unused: {
|
|||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f1(a, eval, c, d, e) {
|
function o(k) {
|
||||||
return a('c') + eval;
|
return { c: 14 }[k];
|
||||||
}
|
|
||||||
function f2(a, b, c, d, e) {
|
|
||||||
return a + eval('c');
|
|
||||||
}
|
|
||||||
function f3(a, eval, c, d, e) {
|
|
||||||
return a + eval('c');
|
|
||||||
}
|
}
|
||||||
|
console.log(function f1(a, eval, c, d, e) {
|
||||||
|
return a("c") + eval;
|
||||||
|
}(o, 28, true));
|
||||||
|
console.log(function f2(a, b, c, d, e) {
|
||||||
|
return a + eval("c");
|
||||||
|
}(14, true, 28));
|
||||||
|
console.log(function f3(a, eval, c, d, e) {
|
||||||
|
return a + eval("c");
|
||||||
|
}(28, o, true));
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f1(a, eval) {
|
function o(k) {
|
||||||
return a('c') + eval;
|
return { c: 14 }[k];
|
||||||
}
|
|
||||||
function f2(a, b, c, d, e) {
|
|
||||||
return a + eval('c');
|
|
||||||
}
|
|
||||||
function f3(a, eval, c, d, e) {
|
|
||||||
return a + eval('c');
|
|
||||||
}
|
}
|
||||||
|
console.log(function(a, eval) {
|
||||||
|
return a("c") + eval;
|
||||||
|
}(o, 28));
|
||||||
|
console.log(function f2(a, b, c, d, e) {
|
||||||
|
return a + eval("c");
|
||||||
|
}(14, true, 28));
|
||||||
|
console.log(function f3(a, eval, c, d, e) {
|
||||||
|
return a + eval("c");
|
||||||
|
}(28, o, true));
|
||||||
}
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"42",
|
||||||
|
"42",
|
||||||
|
"42",
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
eval_mangle: {
|
eval_mangle: {
|
||||||
mangle = {
|
mangle = {}
|
||||||
};
|
beautify = {
|
||||||
input: {
|
beautify: true,
|
||||||
function f1(a, eval, c, d, e) {
|
|
||||||
return a('c') + eval;
|
|
||||||
}
|
|
||||||
function f2(a, b, c, d, e) {
|
|
||||||
return a + eval('c');
|
|
||||||
}
|
|
||||||
function f3(a, eval, c, d, e) {
|
|
||||||
return a + eval('c');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
expect_exact: 'function f1(n,c,e,a,f){return n("c")+c}function f2(a,b,c,d,e){return a+eval("c")}function f3(a,eval,c,d,e){return a+eval("c")}'
|
input: {
|
||||||
|
function o(k) {
|
||||||
|
return { cc: 14 }[k + "c"];
|
||||||
|
}
|
||||||
|
console.log(function f1(a, eval, c, d, e) {
|
||||||
|
return a("c") + eval;
|
||||||
|
}(o, 28, true));
|
||||||
|
console.log(function f2(a, b, c, d, e) {
|
||||||
|
return a + eval("c");
|
||||||
|
}(14, true, 28));
|
||||||
|
console.log(function f3(a, eval, c, d, e) {
|
||||||
|
return a + eval("c");
|
||||||
|
}(28, o, true));
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"function o(o) {",
|
||||||
|
" return {",
|
||||||
|
" cc: 14",
|
||||||
|
' }[o + "c"];',
|
||||||
|
"}",
|
||||||
|
"",
|
||||||
|
"console.log(function o(c, e, n, r, t) {",
|
||||||
|
' return c("c") + e;',
|
||||||
|
"}(o, 28, true));",
|
||||||
|
"",
|
||||||
|
"console.log(function f2(a, b, c, d, e) {",
|
||||||
|
' return a + eval("c");',
|
||||||
|
"}(14, true, 28));",
|
||||||
|
"",
|
||||||
|
"console.log(function f3(a, eval, c, d, e) {",
|
||||||
|
' return a + eval("c");',
|
||||||
|
"}(28, o, true));",
|
||||||
|
]
|
||||||
|
expect_stdout: [
|
||||||
|
"42",
|
||||||
|
"42",
|
||||||
|
"42",
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -790,7 +790,7 @@ issue_3795: {
|
|||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
join_vars: true,
|
join_vars: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
loops: true,
|
loops: true,
|
||||||
passes: 2,
|
passes: 2,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
|
|||||||
@@ -18,43 +18,6 @@ keep_fargs_false: {
|
|||||||
function j(e) {}
|
function j(e) {}
|
||||||
console.log(h(), i().length, j.length);
|
console.log(h(), i().length, j.length);
|
||||||
}
|
}
|
||||||
expect: {
|
|
||||||
console.log(function f() {
|
|
||||||
return f.length;
|
|
||||||
}(), function g() {
|
|
||||||
return g;
|
|
||||||
}().length);
|
|
||||||
function h() {
|
|
||||||
return h.length;
|
|
||||||
}
|
|
||||||
function i() {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
function j() {}
|
|
||||||
console.log(h(), i().length, j.length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
keep_fargs_strict: {
|
|
||||||
options = {
|
|
||||||
keep_fargs: "strict",
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
console.log(function f(a) {
|
|
||||||
return f.length;
|
|
||||||
}(), function g(b) {
|
|
||||||
return g;
|
|
||||||
}().length);
|
|
||||||
function h(c) {
|
|
||||||
return h.length;
|
|
||||||
}
|
|
||||||
function i(d) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
function j(e) {}
|
|
||||||
console.log(h(), i().length, j.length);
|
|
||||||
}
|
|
||||||
expect: {
|
expect: {
|
||||||
console.log(function f(a) {
|
console.log(function f(a) {
|
||||||
return f.length;
|
return f.length;
|
||||||
@@ -117,61 +80,11 @@ keep_fargs_true: {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
replace_index: {
|
|
||||||
options = {
|
|
||||||
arguments: true,
|
|
||||||
evaluate: true,
|
|
||||||
keep_fargs: "strict",
|
|
||||||
properties: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var arguments = [];
|
|
||||||
console.log(arguments[0]);
|
|
||||||
(function() {
|
|
||||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
|
||||||
})("bar", 42);
|
|
||||||
(function(a, b) {
|
|
||||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
|
||||||
})("bar", 42);
|
|
||||||
(function(arguments) {
|
|
||||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
|
||||||
})("bar", 42);
|
|
||||||
(function() {
|
|
||||||
var arguments;
|
|
||||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
|
||||||
})("bar", 42);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var arguments = [];
|
|
||||||
console.log(arguments[0]);
|
|
||||||
(function(argument_0, argument_1) {
|
|
||||||
console.log(argument_1, argument_1, arguments.foo);
|
|
||||||
})("bar", 42);
|
|
||||||
(function(a, b) {
|
|
||||||
console.log(b, b, arguments.foo);
|
|
||||||
})("bar", 42);
|
|
||||||
(function(arguments) {
|
|
||||||
console.log(arguments[1], arguments[1], arguments.foo);
|
|
||||||
})("bar", 42);
|
|
||||||
(function() {
|
|
||||||
var arguments;
|
|
||||||
console.log(arguments[1], arguments[1], arguments.foo);
|
|
||||||
})("bar", 42);
|
|
||||||
}
|
|
||||||
expect_stdout: [
|
|
||||||
"undefined",
|
|
||||||
"42 42 undefined",
|
|
||||||
"42 42 undefined",
|
|
||||||
"a a undefined",
|
|
||||||
"42 42 undefined",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
replace_index_strict: {
|
replace_index_strict: {
|
||||||
options = {
|
options = {
|
||||||
arguments: true,
|
arguments: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
properties: true,
|
properties: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
}
|
}
|
||||||
@@ -202,7 +115,7 @@ replace_index_strict: {
|
|||||||
issue_1858: {
|
issue_1858: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
pure_getters: true,
|
pure_getters: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
@@ -224,7 +137,7 @@ issue_1858: {
|
|||||||
issue_2187_2: {
|
issue_2187_2: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -245,7 +158,7 @@ issue_2187_2: {
|
|||||||
issue_2203_2: {
|
issue_2203_2: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -280,7 +193,7 @@ issue_2203_2: {
|
|||||||
issue_2298: {
|
issue_2298: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
passes: 2,
|
passes: 2,
|
||||||
reduce_funcs: true,
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
@@ -323,7 +236,7 @@ issue_2298: {
|
|||||||
issue_2319_1: {
|
issue_2319_1: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -346,7 +259,7 @@ issue_2319_1: {
|
|||||||
issue_2319_2: {
|
issue_2319_2: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -371,7 +284,7 @@ issue_2319_2: {
|
|||||||
issue_2319_3: {
|
issue_2319_3: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -396,7 +309,7 @@ issue_2319_3: {
|
|||||||
issue_2425_1: {
|
issue_2425_1: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -419,7 +332,7 @@ issue_2425_1: {
|
|||||||
issue_2425_2: {
|
issue_2425_2: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -442,7 +355,7 @@ issue_2425_2: {
|
|||||||
issue_2425_3: {
|
issue_2425_3: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -465,7 +378,7 @@ issue_2425_3: {
|
|||||||
issue_2436_13: {
|
issue_2436_13: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
passes: 2,
|
passes: 2,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -499,7 +412,7 @@ issue_2436_13: {
|
|||||||
issue_2506: {
|
issue_2506: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
passes: 2,
|
passes: 2,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -538,7 +451,7 @@ issue_2506: {
|
|||||||
|
|
||||||
issue_2226_1: {
|
issue_2226_1: {
|
||||||
options = {
|
options = {
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
@@ -585,7 +498,7 @@ issue_2226_1: {
|
|||||||
issue_2226_2: {
|
issue_2226_2: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
sequences: true,
|
sequences: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -607,7 +520,7 @@ issue_2226_2: {
|
|||||||
issue_2226_3: {
|
issue_2226_3: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
@@ -627,7 +540,7 @@ issue_2226_3: {
|
|||||||
|
|
||||||
issue_3192: {
|
issue_3192: {
|
||||||
options = {
|
options = {
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -657,7 +570,7 @@ issue_3192: {
|
|||||||
if_increment: {
|
if_increment: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
@@ -679,7 +592,7 @@ if_increment: {
|
|||||||
try_increment: {
|
try_increment: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
@@ -703,7 +616,7 @@ try_increment: {
|
|||||||
issue_2630_3: {
|
issue_2630_3: {
|
||||||
options = {
|
options = {
|
||||||
inline: true,
|
inline: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
@@ -740,7 +653,7 @@ issue_2630_3: {
|
|||||||
issue_3364: {
|
issue_3364: {
|
||||||
options = {
|
options = {
|
||||||
functions: true,
|
functions: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -805,7 +718,7 @@ issue_3364: {
|
|||||||
|
|
||||||
defun_label: {
|
defun_label: {
|
||||||
options = {
|
options = {
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
passes: 2,
|
passes: 2,
|
||||||
reduce_funcs: true,
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
@@ -837,7 +750,7 @@ defun_label: {
|
|||||||
|
|
||||||
iife_func_side_effects: {
|
iife_func_side_effects: {
|
||||||
options = {
|
options = {
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
reduce_funcs: true,
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -889,7 +802,7 @@ iife_func_side_effects: {
|
|||||||
issue_1595_1: {
|
issue_1595_1: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
reduce_funcs: true,
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -909,7 +822,7 @@ issue_1595_1: {
|
|||||||
issue_1595_2: {
|
issue_1595_2: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
reduce_funcs: true,
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -929,7 +842,7 @@ issue_1595_2: {
|
|||||||
issue_1595_3: {
|
issue_1595_3: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
passes: 2,
|
passes: 2,
|
||||||
reduce_funcs: true,
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
@@ -950,7 +863,7 @@ issue_1595_3: {
|
|||||||
issue_1595_4: {
|
issue_1595_4: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
reduce_funcs: true,
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -972,7 +885,7 @@ issue_1595_4: {
|
|||||||
|
|
||||||
duplicate_lambda_defun_name_1: {
|
duplicate_lambda_defun_name_1: {
|
||||||
options = {
|
options = {
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -992,7 +905,7 @@ duplicate_lambda_defun_name_1: {
|
|||||||
|
|
||||||
duplicate_lambda_defun_name_2: {
|
duplicate_lambda_defun_name_2: {
|
||||||
options = {
|
options = {
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
passes: 2,
|
passes: 2,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -1013,7 +926,7 @@ duplicate_lambda_defun_name_2: {
|
|||||||
|
|
||||||
function_name_mangle: {
|
function_name_mangle: {
|
||||||
options = {
|
options = {
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
keep_fnames: true,
|
keep_fnames: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -1031,7 +944,7 @@ function_name_mangle: {
|
|||||||
|
|
||||||
function_name_mangle_ie8: {
|
function_name_mangle_ie8: {
|
||||||
options = {
|
options = {
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
keep_fnames: true,
|
keep_fnames: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -1052,7 +965,7 @@ function_name_mangle_ie8: {
|
|||||||
|
|
||||||
issue_3420_1: {
|
issue_3420_1: {
|
||||||
options = {
|
options = {
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -1075,7 +988,7 @@ issue_3420_1: {
|
|||||||
issue_3420_2: {
|
issue_3420_2: {
|
||||||
options = {
|
options = {
|
||||||
inline: true,
|
inline: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -1096,7 +1009,7 @@ issue_3420_2: {
|
|||||||
issue_3420_3: {
|
issue_3420_3: {
|
||||||
options = {
|
options = {
|
||||||
inline: true,
|
inline: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
@@ -1118,7 +1031,7 @@ issue_3420_3: {
|
|||||||
|
|
||||||
issue_3423_1: {
|
issue_3423_1: {
|
||||||
options = {
|
options = {
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -1138,7 +1051,7 @@ issue_3423_1: {
|
|||||||
|
|
||||||
issue_3423_2: {
|
issue_3423_2: {
|
||||||
options = {
|
options = {
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -1165,7 +1078,7 @@ collapse_vars_repeated: {
|
|||||||
hoist_funs: true,
|
hoist_funs: true,
|
||||||
if_return: true,
|
if_return: true,
|
||||||
join_vars: true,
|
join_vars: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
loops: true,
|
loops: true,
|
||||||
properties: true,
|
properties: true,
|
||||||
reduce_funcs: true,
|
reduce_funcs: true,
|
||||||
@@ -1212,7 +1125,7 @@ collapse_vars_repeated: {
|
|||||||
chained_3: {
|
chained_3: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -1236,7 +1149,7 @@ replace_all_var_scope: {
|
|||||||
rename = true
|
rename = true
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
mangle = {}
|
mangle = {}
|
||||||
@@ -1265,7 +1178,7 @@ replace_all_var_scope: {
|
|||||||
|
|
||||||
issue_1583: {
|
issue_1583: {
|
||||||
options = {
|
options = {
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
passes: 2,
|
passes: 2,
|
||||||
reduce_funcs: true,
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
@@ -1302,7 +1215,7 @@ issues_3267_1: {
|
|||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
inline: true,
|
inline: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
sequences: true,
|
sequences: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
@@ -1331,7 +1244,7 @@ issues_3267_1: {
|
|||||||
|
|
||||||
trailing_argument_side_effects: {
|
trailing_argument_side_effects: {
|
||||||
options = {
|
options = {
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -1355,7 +1268,7 @@ trailing_argument_side_effects: {
|
|||||||
|
|
||||||
recursive_iife_1: {
|
recursive_iife_1: {
|
||||||
options = {
|
options = {
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
@@ -1374,7 +1287,7 @@ recursive_iife_1: {
|
|||||||
|
|
||||||
recursive_iife_2: {
|
recursive_iife_2: {
|
||||||
options = {
|
options = {
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
@@ -1452,3 +1365,37 @@ issue_3619: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4353_1: {
|
||||||
|
options = {
|
||||||
|
keep_fargs: false,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function f(a) {}.length);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a) {}.length);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4353_2: {
|
||||||
|
options = {
|
||||||
|
keep_fargs: false,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function f(a) {
|
||||||
|
while (console.log("PASS"));
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
while (console.log("PASS"));
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -207,3 +207,123 @@ labels_10: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4466_1: {
|
||||||
|
mangle = {
|
||||||
|
v8: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
A: if (console.log("PASS"))
|
||||||
|
B:;
|
||||||
|
else
|
||||||
|
C:;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
e: if (console.log("PASS"))
|
||||||
|
l:;
|
||||||
|
else
|
||||||
|
l:;
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=12"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4466_1_v8: {
|
||||||
|
mangle = {
|
||||||
|
v8: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
A: if (console.log("PASS"))
|
||||||
|
B:;
|
||||||
|
else
|
||||||
|
C:;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
e: if (console.log("PASS"))
|
||||||
|
l:;
|
||||||
|
else
|
||||||
|
o:;
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=12"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4466_2: {
|
||||||
|
mangle = {
|
||||||
|
toplevel: false,
|
||||||
|
v8: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
if (console.log("PASS"))
|
||||||
|
A:;
|
||||||
|
else
|
||||||
|
B:;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
if (console.log("PASS"))
|
||||||
|
e:;
|
||||||
|
else
|
||||||
|
e:;
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4466_2_v8: {
|
||||||
|
mangle = {
|
||||||
|
toplevel: false,
|
||||||
|
v8: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
if (console.log("PASS"))
|
||||||
|
A:;
|
||||||
|
else
|
||||||
|
B:;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
if (console.log("PASS"))
|
||||||
|
e:;
|
||||||
|
else
|
||||||
|
l:;
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4466_2_toplevel: {
|
||||||
|
mangle = {
|
||||||
|
toplevel: true,
|
||||||
|
v8: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
if (console.log("PASS"))
|
||||||
|
A:;
|
||||||
|
else
|
||||||
|
B:;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
if (console.log("PASS"))
|
||||||
|
e:;
|
||||||
|
else
|
||||||
|
e:;
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4466_2_toplevel_v8: {
|
||||||
|
mangle = {
|
||||||
|
toplevel: true,
|
||||||
|
v8: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
if (console.log("PASS"))
|
||||||
|
A:;
|
||||||
|
else
|
||||||
|
B:;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
if (console.log("PASS"))
|
||||||
|
e:;
|
||||||
|
else
|
||||||
|
e:;
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -359,6 +359,28 @@ reduce_block_2_toplevel: {
|
|||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reduce_vars: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
let a = "PASS";
|
||||||
|
console.log(a);
|
||||||
|
a = "FAIL";
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
console.log("PASS");
|
||||||
|
"FAIL";
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
hoist_props: {
|
hoist_props: {
|
||||||
options = {
|
options = {
|
||||||
hoist_props: true,
|
hoist_props: true,
|
||||||
@@ -1228,3 +1250,92 @@ issue_1753_toplevel: {
|
|||||||
expect_stdout: "0"
|
expect_stdout: "0"
|
||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4438: {
|
||||||
|
options = {
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
function f() {
|
||||||
|
if (console) {
|
||||||
|
{
|
||||||
|
let a = console.log;
|
||||||
|
return void a("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
function f() {
|
||||||
|
if (!console)
|
||||||
|
;
|
||||||
|
else {
|
||||||
|
let a = console.log;
|
||||||
|
a("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4531_1: {
|
||||||
|
mangle = {
|
||||||
|
ie8: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
var a;
|
||||||
|
console.log(function a() {
|
||||||
|
let a;
|
||||||
|
var b;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
var o;
|
||||||
|
console.log(function o() {
|
||||||
|
let o;
|
||||||
|
var t;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4531_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
ie8: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
ie8: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
var a = console;
|
||||||
|
console.log(typeof a, function a() {
|
||||||
|
let { [console]: a } = 0 && a;
|
||||||
|
var b = console;
|
||||||
|
while (!b);
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
var o = console;
|
||||||
|
console.log(typeof o, function o() {
|
||||||
|
let { [console]: o } = 0;
|
||||||
|
var e = console;
|
||||||
|
while (!e);
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "object undefined"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1026,7 +1026,7 @@ issue_4075: {
|
|||||||
|
|
||||||
issue_4082: {
|
issue_4082: {
|
||||||
options = {
|
options = {
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
loops: true,
|
loops: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
@@ -1050,7 +1050,7 @@ issue_4082: {
|
|||||||
|
|
||||||
issue_4084: {
|
issue_4084: {
|
||||||
options = {
|
options = {
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
loops: true,
|
loops: true,
|
||||||
passes: 2,
|
passes: 2,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
@@ -1255,3 +1255,58 @@ issue_4240: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4355: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
loops: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
while (function() {
|
||||||
|
var a;
|
||||||
|
for (a in console.log("PASS"))
|
||||||
|
var b = 0;
|
||||||
|
}())
|
||||||
|
var c;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
console.log("PASS");
|
||||||
|
})();
|
||||||
|
var c;
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4564: {
|
||||||
|
options = {
|
||||||
|
loops: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
throw null;
|
||||||
|
} catch (a) {
|
||||||
|
var a;
|
||||||
|
(function() {
|
||||||
|
for (a in "foo");
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
throw null;
|
||||||
|
} catch (a) {
|
||||||
|
var a;
|
||||||
|
(function() {
|
||||||
|
for (a in "foo");
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "2"
|
||||||
|
}
|
||||||
|
|||||||
@@ -327,7 +327,7 @@ issue_4103: {
|
|||||||
|
|
||||||
issue_4107: {
|
issue_4107: {
|
||||||
options = {
|
options = {
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
merge_vars: true,
|
merge_vars: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
|
|||||||
@@ -338,7 +338,7 @@ evaluate_3: {
|
|||||||
console.log(1 + Number(x) + 2);
|
console.log(1 + Number(x) + 2);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log(+x + 3);
|
console.log(+("" + x) + 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1386,3 +1386,75 @@ issue_4142: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "0"
|
expect_stdout: "0"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4542_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
unsafe_math: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a) {
|
||||||
|
return a / (1 / (a[0] = 2));
|
||||||
|
}([ 3 ]));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a) {
|
||||||
|
return a / (1 / (a[0] = 2));
|
||||||
|
}([ 3 ]));
|
||||||
|
}
|
||||||
|
expect_stdout: "4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4542_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
unsafe_math: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a) {
|
||||||
|
return a / (1 / --a[0]);
|
||||||
|
}([ 3 ]));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a) {
|
||||||
|
return a / (1 / --a[0]);
|
||||||
|
}([ 3 ]));
|
||||||
|
}
|
||||||
|
expect_stdout: "4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4542_3: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
unsafe_math: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a) {
|
||||||
|
return a / (0 / (a[0] = 0, 1));
|
||||||
|
}([ 1 ]));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a) {
|
||||||
|
return a / (0 / (a[0] = 0, 1));
|
||||||
|
}([ 1 ]));
|
||||||
|
}
|
||||||
|
expect_stdout: "NaN"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4542_4: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
unsafe_math: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a) {
|
||||||
|
return a / (1 / (a.length = 1));
|
||||||
|
}([ 2, 3 ]));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a) {
|
||||||
|
return a / (1 / (a.length = 1));
|
||||||
|
}([ 2, 3 ]));
|
||||||
|
}
|
||||||
|
expect_stdout: "2"
|
||||||
|
}
|
||||||
|
|||||||
@@ -45,8 +45,8 @@ duplicate_key_strict: {
|
|||||||
"use strict";
|
"use strict";
|
||||||
var o = {
|
var o = {
|
||||||
a: 1,
|
a: 1,
|
||||||
b: 2,
|
|
||||||
a: 3,
|
a: 3,
|
||||||
|
b: 2,
|
||||||
};
|
};
|
||||||
for (var k in o)
|
for (var k in o)
|
||||||
console.log(k, o[k]);
|
console.log(k, o[k]);
|
||||||
@@ -257,6 +257,29 @@ keep_computed_key: {
|
|||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shorthand_keywords: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unsafe: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var async = 1, get = 2, set = 3, o = {
|
||||||
|
async,
|
||||||
|
get,
|
||||||
|
set,
|
||||||
|
};
|
||||||
|
console.log(o.async, o.get, o.set);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(1, 2, 3);
|
||||||
|
}
|
||||||
|
expect_stdout: "1 2 3"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
issue_4269_1: {
|
issue_4269_1: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
@@ -323,8 +346,8 @@ issue_4269_3: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log({
|
console.log({
|
||||||
["foo"]: "bar",
|
foo: "bar",
|
||||||
get 42() {
|
get [42]() {
|
||||||
return "FAIL";
|
return "FAIL";
|
||||||
},
|
},
|
||||||
42: "PASS",
|
42: "PASS",
|
||||||
@@ -353,10 +376,82 @@ issue_4269_4: {
|
|||||||
get 42() {
|
get 42() {
|
||||||
return "FAIL";
|
return "FAIL";
|
||||||
},
|
},
|
||||||
["foo"]: "bar",
|
foo: "bar",
|
||||||
|
[42]: "PASS",
|
||||||
|
}[42]);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4269_5: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
objects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log({
|
||||||
|
get 42() {
|
||||||
|
return "FAIL";
|
||||||
|
},
|
||||||
|
[console]: "bar",
|
||||||
|
42: "PASS",
|
||||||
|
}[42]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log({
|
||||||
|
get 42() {
|
||||||
|
return "FAIL";
|
||||||
|
},
|
||||||
|
[console]: "bar",
|
||||||
42: "PASS",
|
42: "PASS",
|
||||||
}[42]);
|
}[42]);
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4380: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
objects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log({
|
||||||
|
get 0() {
|
||||||
|
return "FAIL 1";
|
||||||
|
},
|
||||||
|
0: "FAIL 2",
|
||||||
|
[0]: "PASS",
|
||||||
|
}[0]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log({
|
||||||
|
get 0() {
|
||||||
|
return "FAIL 1";
|
||||||
|
},
|
||||||
|
[0]: ("FAIL 2", "PASS"),
|
||||||
|
}[0]);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4415: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
objects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log({
|
||||||
|
["00"]: "FAIL",
|
||||||
|
}[0] || "PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log({
|
||||||
|
"00": "FAIL",
|
||||||
|
}[0] || "PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|||||||
@@ -685,7 +685,7 @@ issue_3858: {
|
|||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
inline: true,
|
inline: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -711,7 +711,7 @@ inline_pure_call_1: {
|
|||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
inline: true,
|
inline: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
sequences: true,
|
sequences: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
@@ -733,7 +733,7 @@ inline_pure_call_2: {
|
|||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
inline: true,
|
inline: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
sequences: true,
|
sequences: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
@@ -756,7 +756,7 @@ inline_pure_call_3: {
|
|||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
inline: true,
|
inline: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
passes: 2,
|
passes: 2,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
|
|||||||
@@ -979,6 +979,7 @@ collapse_vars_2_strict: {
|
|||||||
collapse_rhs_true: {
|
collapse_rhs_true: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
pure_getters: true,
|
pure_getters: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -1015,6 +1016,7 @@ collapse_rhs_true: {
|
|||||||
collapse_rhs_false: {
|
collapse_rhs_false: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
pure_getters: false,
|
pure_getters: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -1051,6 +1053,7 @@ collapse_rhs_false: {
|
|||||||
collapse_rhs_strict: {
|
collapse_rhs_strict: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
pure_getters: "strict",
|
pure_getters: "strict",
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -1087,6 +1090,7 @@ collapse_rhs_strict: {
|
|||||||
collapse_rhs_setter: {
|
collapse_rhs_setter: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
pure_getters: "strict",
|
pure_getters: "strict",
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -1208,3 +1212,32 @@ issue_3427: {
|
|||||||
expect: {}
|
expect: {}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4440: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
(function() {
|
||||||
|
arguments = null;
|
||||||
|
console.log(arguments.p = "FAIL");
|
||||||
|
})();
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
(function() {
|
||||||
|
arguments = null;
|
||||||
|
console.log(arguments.p = "FAIL");
|
||||||
|
})();
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -2373,7 +2373,7 @@ redefine_farg_1: {
|
|||||||
function f(a) {
|
function f(a) {
|
||||||
return typeof a;
|
return typeof a;
|
||||||
}
|
}
|
||||||
function g() {
|
function g(a) {
|
||||||
return "number";
|
return "number";
|
||||||
}
|
}
|
||||||
function h(a, b) {
|
function h(a, b) {
|
||||||
@@ -6928,7 +6928,7 @@ issue_3622: {
|
|||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
inline: true,
|
inline: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
sequences: true,
|
sequences: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
@@ -7196,7 +7196,7 @@ issue_3894: {
|
|||||||
issue_3922: {
|
issue_3922: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
pure_getters: "strict",
|
pure_getters: "strict",
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
@@ -7601,3 +7601,32 @@ issue_4188_2: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "number undefined"
|
expect_stdout: "number undefined"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4568: {
|
||||||
|
options = {
|
||||||
|
booleans: true,
|
||||||
|
conditionals: true,
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
loops: true,
|
||||||
|
passes: 2,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a) {
|
||||||
|
a && console.log("FAIL");
|
||||||
|
if (1)
|
||||||
|
do {
|
||||||
|
if (!console.log("PASS")) break;
|
||||||
|
} while (1);
|
||||||
|
})(!(0 !== delete NaN));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a) {
|
||||||
|
for (a && console.log("FAIL"), 1; console.log("PASS"); ) 1;
|
||||||
|
})(!(0 !== delete NaN));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
698
test/compress/rests.js
Normal file
698
test/compress/rests.js
Normal file
@@ -0,0 +1,698 @@
|
|||||||
|
arrow_1: {
|
||||||
|
input: {
|
||||||
|
console.log.apply(console, ((...a) => a)("PASS", 42));
|
||||||
|
}
|
||||||
|
expect_exact: 'console.log.apply(console,((...a)=>a)("PASS",42));'
|
||||||
|
expect_stdout: "PASS 42"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
arrow_2: {
|
||||||
|
input: {
|
||||||
|
console.log.apply(console, ((a, ...b) => b)("FAIL", "PASS", 42));
|
||||||
|
}
|
||||||
|
expect_exact: 'console.log.apply(console,((a,...b)=>b)("FAIL","PASS",42));'
|
||||||
|
expect_stdout: "PASS 42"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
arrow_destructured_array_1: {
|
||||||
|
input: {
|
||||||
|
console.log.apply(console, (([ ...a ]) => a)("PASS"));
|
||||||
|
}
|
||||||
|
expect_exact: 'console.log.apply(console,(([...a])=>a)("PASS"));'
|
||||||
|
expect_stdout: "P A S S"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
arrow_destructured_array_2: {
|
||||||
|
input: {
|
||||||
|
console.log.apply(console, (([ a, ...b ]) => b)([ "FAIL", "PASS", 42 ]));
|
||||||
|
}
|
||||||
|
expect_exact: 'console.log.apply(console,(([a,...b])=>b)(["FAIL","PASS",42]));'
|
||||||
|
expect_stdout: "PASS 42"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
arrow_destructured_array_3: {
|
||||||
|
input: {
|
||||||
|
console.log((([ [ ...a ] = "FAIL" ]) => a)([ "PASS" ]).join("|"));
|
||||||
|
}
|
||||||
|
expect_exact: 'console.log((([[...a]="FAIL"])=>a)(["PASS"]).join("|"));'
|
||||||
|
expect_stdout: "P|A|S|S"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
arrow_destructured_object_1: {
|
||||||
|
input: {
|
||||||
|
var f = ({ ...a }) => a, o = f({ PASS: 42 });
|
||||||
|
for (var k in o)
|
||||||
|
console.log(k, o[k]);
|
||||||
|
}
|
||||||
|
expect_exact: "var f=({...a})=>a,o=f({PASS:42});for(var k in o)console.log(k,o[k]);"
|
||||||
|
expect_stdout: "PASS 42"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
arrow_destructured_object_2: {
|
||||||
|
input: {
|
||||||
|
var f = ({ FAIL: a, ...b }) => b, o = f({ PASS: 42, FAIL: null });
|
||||||
|
for (var k in o)
|
||||||
|
console.log(k, o[k]);
|
||||||
|
}
|
||||||
|
expect_exact: "var f=({FAIL:a,...b})=>b,o=f({PASS:42,FAIL:null});for(var k in o)console.log(k,o[k]);"
|
||||||
|
expect_stdout: "PASS 42"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
arrow_destructured_object_3: {
|
||||||
|
input: {
|
||||||
|
var f = ([ { ...a } = [ "FAIL" ] ]) => a;
|
||||||
|
var o = f([ "PASS" ]);
|
||||||
|
for (var k in o)
|
||||||
|
console.log(k, o[k]);
|
||||||
|
}
|
||||||
|
expect_exact: 'var f=([{...a}=["FAIL"]])=>a;var o=f(["PASS"]);for(var k in o)console.log(k,o[k]);'
|
||||||
|
expect_stdout: [
|
||||||
|
"0 P",
|
||||||
|
"1 A",
|
||||||
|
"2 S",
|
||||||
|
"3 S",
|
||||||
|
]
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
funarg_1: {
|
||||||
|
input: {
|
||||||
|
console.log.apply(console, function(...a) {
|
||||||
|
return a;
|
||||||
|
}("PASS", 42));
|
||||||
|
}
|
||||||
|
expect_exact: 'console.log.apply(console,function(...a){return a}("PASS",42));'
|
||||||
|
expect_stdout: "PASS 42"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
funarg_2: {
|
||||||
|
input: {
|
||||||
|
console.log.apply(console, function(a, ...b) {
|
||||||
|
return b;
|
||||||
|
}("FAIL", "PASS", 42));
|
||||||
|
}
|
||||||
|
expect_exact: 'console.log.apply(console,function(a,...b){return b}("FAIL","PASS",42));'
|
||||||
|
expect_stdout: "PASS 42"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
destructured_array_1: {
|
||||||
|
input: {
|
||||||
|
var [ ...a ] = [ "PASS", 42 ];
|
||||||
|
console.log.apply(console, a);
|
||||||
|
}
|
||||||
|
expect_exact: 'var[...a]=["PASS",42];console.log.apply(console,a);'
|
||||||
|
expect_stdout: "PASS 42"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
destructured_array_2: {
|
||||||
|
input: {
|
||||||
|
var [ a, ...b ] = [ "FAIL", "PASS", 42 ];
|
||||||
|
console.log.apply(console, b);
|
||||||
|
}
|
||||||
|
expect_exact: 'var[a,...b]=["FAIL","PASS",42];console.log.apply(console,b);'
|
||||||
|
expect_stdout: "PASS 42"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
destructured_object_1: {
|
||||||
|
input: {
|
||||||
|
var { ...a } = [ "FAIL", "PASS", 42 ];
|
||||||
|
console.log(a[1], a[2]);
|
||||||
|
}
|
||||||
|
expect_exact: 'var{...a}=["FAIL","PASS",42];console.log(a[1],a[2]);'
|
||||||
|
expect_stdout: "PASS 42"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
destructured_object_2: {
|
||||||
|
input: {
|
||||||
|
var { 0: a, ...b } = [ "FAIL", "PASS", 42 ];
|
||||||
|
console.log(b[1], b[2]);
|
||||||
|
}
|
||||||
|
expect_exact: 'var{0:a,...b}=["FAIL","PASS",42];console.log(b[1],b[2]);'
|
||||||
|
expect_stdout: "PASS 42"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_fargs: {
|
||||||
|
options = {
|
||||||
|
keep_fargs: false,
|
||||||
|
rests: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a, ...b) {
|
||||||
|
return b[0];
|
||||||
|
}("FAIL", "PASS"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(b) {
|
||||||
|
return b[0];
|
||||||
|
}([ "PASS" ]));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
inline: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a, ...[ b, c ]) {
|
||||||
|
return c + b + a;
|
||||||
|
}("SS", "A", "P"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(([ a, ...[ b, c ] ] = [ "SS", "A", "P" ], c + b + a));
|
||||||
|
var a, b, c;
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
retain_var: {
|
||||||
|
options = {
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var [ ...a ] = [ "PASS" ];
|
||||||
|
console.log(a[0]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var [ ...a ] = [ "PASS" ];
|
||||||
|
console.log(a[0]);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce_destructured_array: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
rests: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var [ ...a ] = [ "PASS" ];
|
||||||
|
console.log(a[0]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log([ "PASS" ][0]);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce_destructured_object: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var { ...a } = [ "PASS" ];
|
||||||
|
console.log(a[0]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var { ...a } = [ "PASS" ];
|
||||||
|
console.log(a[0]);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
retain_destructured_array: {
|
||||||
|
options = {
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var [ a, ...b ] = [ "FAIL", "PASS", 42 ];
|
||||||
|
console.log.apply(console, b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var [ , ...b ] = [ "FAIL", "PASS", 42 ];
|
||||||
|
console.log.apply(console, b);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS 42"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
retain_destructured_object_1: {
|
||||||
|
options = {
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var { 0: a, ...b } = [ "FAIL", "PASS", 42 ];
|
||||||
|
for (var k in b)
|
||||||
|
console.log(k, b[k]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var { 0: a, ...b } = [ "FAIL", "PASS", 42 ];
|
||||||
|
for (var k in b)
|
||||||
|
console.log(k, b[k]);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1 PASS",
|
||||||
|
"2 42",
|
||||||
|
]
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
retain_destructured_object_2: {
|
||||||
|
options = {
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var { foo: [ a ], ...b } = { foo: [ "FAIL" ], bar: "PASS", baz: 42 };
|
||||||
|
for (var k in b)
|
||||||
|
console.log(k, b[k]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var { foo: [], ...b } = { foo: [ "FAIL" ], bar: "PASS", baz: 42 };
|
||||||
|
for (var k in b)
|
||||||
|
console.log(k, b[k]);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"bar PASS",
|
||||||
|
"baz 42",
|
||||||
|
]
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
retain_funarg_destructured_array_1: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
pure_getters: "strict",
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log((([ ...a ]) => a)([ "PASS" ])[0]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log((([ ...a ]) => a)([ "PASS" ])[0]);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
retain_funarg_destructured_array_2: {
|
||||||
|
options = {
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function([ a, ...b ]) {
|
||||||
|
return b;
|
||||||
|
}("bar")[1]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function([ , ...b ]) {
|
||||||
|
return b;
|
||||||
|
}("bar")[1]);
|
||||||
|
}
|
||||||
|
expect_stdout: "r"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
retain_funarg_destructured_object_1: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
pure_getters: "strict",
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log((({ ...a }) => a)([ "PASS" ])[0]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log((({ ...a }) => a)([ "PASS" ])[0]);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
retain_funarg_destructured_object_2: {
|
||||||
|
options = {
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function({ p: a, ... b }) {
|
||||||
|
return b;
|
||||||
|
}({ p: "FAIL" }).p || "PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function({ p: a, ... b }) {
|
||||||
|
return b;
|
||||||
|
}({ p: "FAIL" }).p || "PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_unused_call_args_1: {
|
||||||
|
options = {
|
||||||
|
rests: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(...a) {
|
||||||
|
console.log(a[0]);
|
||||||
|
})(42, console.log("PASS"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a) {
|
||||||
|
console.log(a[0]);
|
||||||
|
})([ 42, console.log("PASS") ]);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"PASS",
|
||||||
|
"42",
|
||||||
|
]
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_unused_call_args_2: {
|
||||||
|
options = {
|
||||||
|
keep_fargs: false,
|
||||||
|
rests: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a, ...b) {
|
||||||
|
return b;
|
||||||
|
}(console).length);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(b) {
|
||||||
|
return b;
|
||||||
|
}((console, [])).length);
|
||||||
|
}
|
||||||
|
expect_stdout: "0"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
merge_funarg: {
|
||||||
|
options = {
|
||||||
|
merge_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(...a) {
|
||||||
|
var b = a.length;
|
||||||
|
console.log(b);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(...b) {
|
||||||
|
var b = b.length;
|
||||||
|
console.log(b);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "0"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
merge_funarg_destructured_array: {
|
||||||
|
options = {
|
||||||
|
merge_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function([ ...a ]) {
|
||||||
|
var b = a.length;
|
||||||
|
console.log(b);
|
||||||
|
})([]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function([ ...b ]) {
|
||||||
|
var b = b.length;
|
||||||
|
console.log(b);
|
||||||
|
})([]);
|
||||||
|
}
|
||||||
|
expect_stdout: "0"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
merge_funarg_destructured_object: {
|
||||||
|
options = {
|
||||||
|
merge_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function({ ...a }) {
|
||||||
|
var b = a[0];
|
||||||
|
console.log(b);
|
||||||
|
})([ "PASS" ]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function({ ...b }) {
|
||||||
|
var b = b[0];
|
||||||
|
console.log(b);
|
||||||
|
})([ "PASS" ]);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
keep_arguments: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(...[ {} ]) {
|
||||||
|
console.log(arguments[0]);
|
||||||
|
})("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(...[ {} ]) {
|
||||||
|
console.log(arguments[0]);
|
||||||
|
})("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_rest_array: {
|
||||||
|
options = {
|
||||||
|
rests: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var [ ...[ a ]] = [ "PASS" ];
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var [ a ] = [ "PASS" ];
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_rest_arrow: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
reduce_vars: true,
|
||||||
|
rests: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(((...[ a ]) => a)("PASS"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log((a => a)("PASS"));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_rest_lambda: {
|
||||||
|
options = {
|
||||||
|
keep_fargs: false,
|
||||||
|
reduce_vars: true,
|
||||||
|
rests: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(...[ a ]) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
console.log(f("PASS"), f(42));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
console.log(f("PASS"), f(42));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS 42"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4525_1: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a, ...[]) {
|
||||||
|
a = "FAIL";
|
||||||
|
return arguments[0];
|
||||||
|
}("PASS"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a, ...[]) {
|
||||||
|
a = "FAIL";
|
||||||
|
return arguments[0];
|
||||||
|
}("PASS"));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4525_2: {
|
||||||
|
options = {
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a, ...[]) {
|
||||||
|
a = "FAIL";
|
||||||
|
return arguments[0];
|
||||||
|
}("PASS"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a, ...[]) {
|
||||||
|
a = "FAIL";
|
||||||
|
return arguments[0];
|
||||||
|
}("PASS"));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4538: {
|
||||||
|
options = {
|
||||||
|
rests: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(typeof function f(...a) {
|
||||||
|
return a.p, f;
|
||||||
|
}()());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(typeof function f(...a) {
|
||||||
|
return a.p, f;
|
||||||
|
}()());
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4544_1: {
|
||||||
|
options = {
|
||||||
|
keep_fnames: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
(function f(...[ {} ]) {})();
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
[ ...[ {} ] ] = [];
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4544_2: {
|
||||||
|
options = {
|
||||||
|
keep_fnames: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
(function f(a, ...[ {} ]) {})([]);
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
[ , ...[ {} ] ] = [ [] ];
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4562: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
rests: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log((([ ...[ a ] ]) => a)("foo"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log((([ a ]) => a)("foo"));
|
||||||
|
}
|
||||||
|
expect_stdout: "f"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4575: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
ie8: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
rests: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
A = "PASS";
|
||||||
|
(function() {
|
||||||
|
var a = 0, b = a;
|
||||||
|
var c = function a(...b) {
|
||||||
|
A;
|
||||||
|
var d = A;
|
||||||
|
console.log(d, b.length);
|
||||||
|
}();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
A = "PASS";
|
||||||
|
(function() {
|
||||||
|
(function(b) {
|
||||||
|
A;
|
||||||
|
var d = A;
|
||||||
|
console.log(d, b.length);
|
||||||
|
})([]);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS 0"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
@@ -13,6 +13,23 @@ console_log: {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console_log_console: {
|
||||||
|
input: {
|
||||||
|
var log = console.log;
|
||||||
|
log(console);
|
||||||
|
log(typeof console.log);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var log = console.log;
|
||||||
|
log(console);
|
||||||
|
log(typeof console.log);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"{ log: 'function(){}' }",
|
||||||
|
"function",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
typeof_arguments: {
|
typeof_arguments: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
@@ -81,6 +98,63 @@ log_global: {
|
|||||||
expect_stdout: "[object global]"
|
expect_stdout: "[object global]"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log_nested: {
|
||||||
|
options = {
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = { p: 42 };
|
||||||
|
for (var i = 0; i < 10; i++)
|
||||||
|
o = {
|
||||||
|
p: o,
|
||||||
|
q: function foo() {},
|
||||||
|
};
|
||||||
|
console.log(o);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = { p: 42 };
|
||||||
|
for (var i = 0; i < 10; i++)
|
||||||
|
o = {
|
||||||
|
p: o,
|
||||||
|
q: function() {},
|
||||||
|
};
|
||||||
|
console.log(o);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
timers: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var count = 0, interval = 1000, duration = 3210;
|
||||||
|
var timer = setInterval(function() {
|
||||||
|
console.log(++count);
|
||||||
|
}, interval);
|
||||||
|
setTimeout(function() {
|
||||||
|
clearInterval(timer);
|
||||||
|
}, duration);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var count = 0;
|
||||||
|
var timer = setInterval(function() {
|
||||||
|
console.log(++count);
|
||||||
|
}, 1000);
|
||||||
|
setTimeout(function() {
|
||||||
|
clearInterval(timer);
|
||||||
|
}, 3210);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"3",
|
||||||
|
]
|
||||||
|
node_version: ">=0.12"
|
||||||
|
}
|
||||||
|
|
||||||
issue_4054: {
|
issue_4054: {
|
||||||
input: {
|
input: {
|
||||||
console.log({
|
console.log({
|
||||||
|
|||||||
@@ -436,7 +436,7 @@ trim_new: {
|
|||||||
|
|
||||||
issue_4325: {
|
issue_4325: {
|
||||||
options = {
|
options = {
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
passes: 2,
|
passes: 2,
|
||||||
pure_getters: "strict",
|
pure_getters: "strict",
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
@@ -470,3 +470,39 @@ issue_4325: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4366_1: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
({
|
||||||
|
p: 42,
|
||||||
|
get p() {},
|
||||||
|
q: console.log("PASS"),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4366_2: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
({
|
||||||
|
set p(v) {},
|
||||||
|
q: console.log("PASS"),
|
||||||
|
p: 42,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|||||||
920
test/compress/spreads.js
Normal file
920
test/compress/spreads.js
Normal file
@@ -0,0 +1,920 @@
|
|||||||
|
collapse_vars_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
[ ...a = "PASS", "PASS"].slice();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
[ ...a = "PASS", "PASS"].slice();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
collapse_vars_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "FAIL";
|
||||||
|
try {
|
||||||
|
a = "PASS";
|
||||||
|
[ ...42, "PASS"].slice();
|
||||||
|
} catch (e) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "FAIL";
|
||||||
|
try {
|
||||||
|
a = "PASS";
|
||||||
|
[ ...42, "PASS"].slice();
|
||||||
|
} catch (e) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
collapse_vars_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "FAIL";
|
||||||
|
try {
|
||||||
|
[ ...(a = "PASS", 42), "PASS"].slice();
|
||||||
|
} catch (e) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "FAIL";
|
||||||
|
try {
|
||||||
|
[ ...(a = "PASS", 42), "PASS"].slice();
|
||||||
|
} catch (e) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
collapse_vars_4: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a) {
|
||||||
|
return a;
|
||||||
|
}(...[ "PASS", "FAIL" ]));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a) {
|
||||||
|
return a;
|
||||||
|
}(...[ "PASS", "FAIL" ]));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
conditionals_farg: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function log(msg) {
|
||||||
|
console.log(msg);
|
||||||
|
}
|
||||||
|
var a = 42, b = [ "PASS" ], c = [ "FAIL" ];
|
||||||
|
a ? log(...b) : log(...c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function log(msg) {
|
||||||
|
console.log(msg);
|
||||||
|
}
|
||||||
|
var a = 42, b = [ "PASS" ], c = [ "FAIL" ];
|
||||||
|
log(...a ? b : c);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
dont_inline: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a) {
|
||||||
|
return a;
|
||||||
|
}(...[ "PASS", "FAIL" ]));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a) {
|
||||||
|
return a;
|
||||||
|
}(...[ "PASS", "FAIL" ]));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
do_inline: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
spreads: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a) {
|
||||||
|
return a;
|
||||||
|
}(...[ "PASS", "FAIL" ]));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(("FAIL", "PASS"));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_empty_call_1: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
(function() {})(...null);
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
[ ...null ];
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_empty_call_2: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
spreads: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {})(...[ console.log("PASS") ]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
convert_hole: {
|
||||||
|
options = {
|
||||||
|
spreads: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(...[ "PASS", , 42 ]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("PASS", void 0, 42);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS undefined 42"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
keep_property_access: {
|
||||||
|
options = {
|
||||||
|
properties: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
return [ ..."foo" ][0];
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
return [ ..."foo" ][0];
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "f"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
keep_fargs: {
|
||||||
|
options = {
|
||||||
|
keep_fargs: false,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = [ "PASS" ];
|
||||||
|
(function(b, c) {
|
||||||
|
console.log(c);
|
||||||
|
})(console, ...a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = [ "PASS" ];
|
||||||
|
(function(b, c) {
|
||||||
|
console.log(c);
|
||||||
|
})(console, ...a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce_vars_1: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(b, c) {
|
||||||
|
return c ? "PASS" : "FAIL";
|
||||||
|
}(..."foo"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(b, c) {
|
||||||
|
return c ? "PASS" : "FAIL";
|
||||||
|
}(..."foo"));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce_vars_2: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(b, c) {
|
||||||
|
return c ? "PASS" : "FAIL";
|
||||||
|
}(..."foo"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(b, c) {
|
||||||
|
return c ? "PASS" : "FAIL";
|
||||||
|
}(..."foo"));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
convert_setter: {
|
||||||
|
options = {
|
||||||
|
objects: true,
|
||||||
|
spreads: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
...{
|
||||||
|
set PASS(v) {},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
for (var k in o)
|
||||||
|
console.log(k, o[k]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
PASS: void 0,
|
||||||
|
};
|
||||||
|
for (var k in o)
|
||||||
|
console.log(k, o[k]);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS undefined"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
keep_getter_1: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
({
|
||||||
|
...{
|
||||||
|
get p() {
|
||||||
|
console.log("PASS");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
get q() {
|
||||||
|
console.log("FAIL");
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
({
|
||||||
|
...{
|
||||||
|
get p() {
|
||||||
|
console.log("PASS");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
keep_getter_2: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
({
|
||||||
|
...(console.log("foo"), {
|
||||||
|
get p() {
|
||||||
|
console.log("bar");
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
({
|
||||||
|
...(console.log("foo"), {
|
||||||
|
get p() {
|
||||||
|
console.log("bar");
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"foo",
|
||||||
|
"bar",
|
||||||
|
]
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
keep_getter_3: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
({
|
||||||
|
...function() {
|
||||||
|
return {
|
||||||
|
get p() {
|
||||||
|
console.log("PASS");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
({
|
||||||
|
...function() {
|
||||||
|
return {
|
||||||
|
get p() {
|
||||||
|
console.log("PASS");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
keep_getter_4: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
get p() {
|
||||||
|
console.log("PASS");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
({
|
||||||
|
q: o,
|
||||||
|
...o,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
get p() {
|
||||||
|
console.log("PASS");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
({
|
||||||
|
...o,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
keep_accessor: {
|
||||||
|
options = {
|
||||||
|
objects: true,
|
||||||
|
spreads: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
...{
|
||||||
|
get p() {
|
||||||
|
console.log("GET");
|
||||||
|
return this.r;
|
||||||
|
},
|
||||||
|
set q(v) {
|
||||||
|
console.log("SET", v);
|
||||||
|
},
|
||||||
|
r: 42,
|
||||||
|
},
|
||||||
|
r: null,
|
||||||
|
};
|
||||||
|
for (var k in o)
|
||||||
|
console.log(k, o[k]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
...{
|
||||||
|
get p() {
|
||||||
|
console.log("GET");
|
||||||
|
return this.r;
|
||||||
|
},
|
||||||
|
set q(v) {
|
||||||
|
console.log("SET", v);
|
||||||
|
},
|
||||||
|
r: 42,
|
||||||
|
},
|
||||||
|
r: null,
|
||||||
|
};
|
||||||
|
for (var k in o)
|
||||||
|
console.log(k, o[k]);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"GET",
|
||||||
|
"p 42",
|
||||||
|
"q undefined",
|
||||||
|
"r null",
|
||||||
|
]
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
object_key_order_1: {
|
||||||
|
options = {
|
||||||
|
objects: true,
|
||||||
|
spreads: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
...{},
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
a: 3,
|
||||||
|
};
|
||||||
|
for (var k in o)
|
||||||
|
console.log(k, o[k]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
a: (1, 3),
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
for (var k in o)
|
||||||
|
console.log(k, o[k]);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"a 3",
|
||||||
|
"b 2",
|
||||||
|
]
|
||||||
|
node_version: ">=8 <=10"
|
||||||
|
}
|
||||||
|
|
||||||
|
object_key_order_2: {
|
||||||
|
options = {
|
||||||
|
objects: true,
|
||||||
|
spreads: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
a: 1,
|
||||||
|
...{},
|
||||||
|
b: 2,
|
||||||
|
a: 3,
|
||||||
|
};
|
||||||
|
for (var k in o)
|
||||||
|
console.log(k, o[k]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
a: (1, 3),
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
for (var k in o)
|
||||||
|
console.log(k, o[k]);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"a 3",
|
||||||
|
"b 2",
|
||||||
|
]
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
object_key_order_3: {
|
||||||
|
options = {
|
||||||
|
objects: true,
|
||||||
|
spreads: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
...{},
|
||||||
|
a: 3,
|
||||||
|
};
|
||||||
|
for (var k in o)
|
||||||
|
console.log(k, o[k]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
a: (1, 3),
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
for (var k in o)
|
||||||
|
console.log(k, o[k]);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"a 3",
|
||||||
|
"b 2",
|
||||||
|
]
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
object_key_order_4: {
|
||||||
|
options = {
|
||||||
|
objects: true,
|
||||||
|
spreads: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
a: 3,
|
||||||
|
...{},
|
||||||
|
};
|
||||||
|
for (var k in o)
|
||||||
|
console.log(k, o[k]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
a: (1, 3),
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
for (var k in o)
|
||||||
|
console.log(k, o[k]);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"a 3",
|
||||||
|
"b 2",
|
||||||
|
]
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
object_spread_array: {
|
||||||
|
options = {
|
||||||
|
objects: true,
|
||||||
|
spreads: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
...[ "foo", "bar" ],
|
||||||
|
};
|
||||||
|
for (var k in o)
|
||||||
|
console.log(k, o[k]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
...[ "foo", "bar" ],
|
||||||
|
};
|
||||||
|
for (var k in o)
|
||||||
|
console.log(k, o[k]);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"0 foo",
|
||||||
|
"1 bar",
|
||||||
|
]
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
object_spread_string: {
|
||||||
|
options = {
|
||||||
|
objects: true,
|
||||||
|
spreads: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
..."foo",
|
||||||
|
};
|
||||||
|
for (var k in o)
|
||||||
|
console.log(k, o[k]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
..."foo",
|
||||||
|
};
|
||||||
|
for (var k in o)
|
||||||
|
console.log(k, o[k]);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"0 f",
|
||||||
|
"1 o",
|
||||||
|
"2 o",
|
||||||
|
]
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
unused_var_side_effects: {
|
||||||
|
options = {
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function f(a) {
|
||||||
|
var b = {
|
||||||
|
...a,
|
||||||
|
};
|
||||||
|
})({
|
||||||
|
get p() {
|
||||||
|
console.log("PASS");
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a) {
|
||||||
|
({
|
||||||
|
...a,
|
||||||
|
});
|
||||||
|
})({
|
||||||
|
get p() {
|
||||||
|
console.log("PASS");
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4329: {
|
||||||
|
options = {
|
||||||
|
objects: true,
|
||||||
|
spreads: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log({
|
||||||
|
...{
|
||||||
|
get 0() {
|
||||||
|
return "FAIL";
|
||||||
|
},
|
||||||
|
...{
|
||||||
|
0: "PASS",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}[0]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log({
|
||||||
|
...{
|
||||||
|
get 0() {
|
||||||
|
return "FAIL";
|
||||||
|
},
|
||||||
|
[0]: "PASS",
|
||||||
|
},
|
||||||
|
}[0]);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4331: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS", b;
|
||||||
|
console,
|
||||||
|
b = a;
|
||||||
|
(function() {
|
||||||
|
a++;
|
||||||
|
})(...a);
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "PASS", b;
|
||||||
|
console;
|
||||||
|
(function() {
|
||||||
|
a++;
|
||||||
|
})(...b = a);
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4342: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
new function() {}(...42);
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
[ ...42 ];
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4345: {
|
||||||
|
options = {
|
||||||
|
objects: true,
|
||||||
|
spreads: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log({
|
||||||
|
...{
|
||||||
|
get 42() {
|
||||||
|
return "FAIL";
|
||||||
|
},
|
||||||
|
...{},
|
||||||
|
42: "PASS",
|
||||||
|
},
|
||||||
|
}[42]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log({
|
||||||
|
...{
|
||||||
|
get 42() {
|
||||||
|
return "FAIL";
|
||||||
|
},
|
||||||
|
[42]: "PASS",
|
||||||
|
},
|
||||||
|
}[42]);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4361: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
var a = console.log("foo");
|
||||||
|
console;
|
||||||
|
var b = {
|
||||||
|
...a,
|
||||||
|
};
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
var a = console.log("foo");
|
||||||
|
console;
|
||||||
|
({
|
||||||
|
...a,
|
||||||
|
});
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"foo",
|
||||||
|
"undefined",
|
||||||
|
]
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4363: {
|
||||||
|
options = {
|
||||||
|
objects: true,
|
||||||
|
spreads: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
({
|
||||||
|
...{
|
||||||
|
set [console.log("PASS")](v) {},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
({
|
||||||
|
[console.log("PASS")]: void 0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4556: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
var a = "" + [ a++ ];
|
||||||
|
var b = [ ...a ];
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
var a;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4560_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0;
|
||||||
|
(function(...{
|
||||||
|
[a++]: {},
|
||||||
|
}) {})(2);
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0;
|
||||||
|
(function(...{
|
||||||
|
[a++]: {},
|
||||||
|
}) {})(2);
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4560_2: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0;
|
||||||
|
(function(...{
|
||||||
|
[a++]: {},
|
||||||
|
}) {})(2);
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0;
|
||||||
|
(function(...{
|
||||||
|
[a++]: {},
|
||||||
|
}) {})(2);
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4560_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0, b;
|
||||||
|
[ ...{
|
||||||
|
[a++]: b,
|
||||||
|
} ] = [ "PASS" ];
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0, b;
|
||||||
|
[ ...{
|
||||||
|
[a++]: b,
|
||||||
|
} ] = [ "PASS" ];
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
8
test/input/invalid/destructured_var.js
Normal file
8
test/input/invalid/destructured_var.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
function f() {
|
||||||
|
var { eval } = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function g() {
|
||||||
|
"use strict";
|
||||||
|
var { eval } = 42;
|
||||||
|
}
|
||||||
3
test/input/reduce/destructured_assign.js
Normal file
3
test/input/reduce/destructured_assign.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
var o = {};
|
||||||
|
[ o[1 + .1 + .1] ] = [ 42 ];
|
||||||
|
console.log(o[1.2]);
|
||||||
17
test/input/reduce/destructured_assign.reduced.js
Normal file
17
test/input/reduce/destructured_assign.reduced.js
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
// (beautified)
|
||||||
|
var o = {};
|
||||||
|
|
||||||
|
[ o[1 + .1 + .1] ] = [];
|
||||||
|
|
||||||
|
console.log(o);
|
||||||
|
// output: { '1.2000000000000002': undefined }
|
||||||
|
//
|
||||||
|
// minify: { '1.2': undefined }
|
||||||
|
//
|
||||||
|
// options: {
|
||||||
|
// "compress": {
|
||||||
|
// "unsafe_math": true
|
||||||
|
// },
|
||||||
|
// "mangle": false,
|
||||||
|
// "validate": true
|
||||||
|
// }
|
||||||
7
test/input/reduce/destructured_catch.js
Normal file
7
test/input/reduce/destructured_catch.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
try {
|
||||||
|
"foo" in 42;
|
||||||
|
} catch ({
|
||||||
|
message,
|
||||||
|
}) {
|
||||||
|
console.log(message);
|
||||||
|
}
|
||||||
13
test/input/reduce/destructured_catch.reduced.js
Normal file
13
test/input/reduce/destructured_catch.reduced.js
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
// (beautified)
|
||||||
|
try {
|
||||||
|
1 in 0;
|
||||||
|
} catch (message) {
|
||||||
|
console.log(message);
|
||||||
|
}
|
||||||
|
// output: TypeError: Cannot use 'in' operator to search for '1' in 0
|
||||||
|
//
|
||||||
|
// minify: TypeError: Cannot use 'in' operator to search for '0' in 0
|
||||||
|
//
|
||||||
|
// options: {
|
||||||
|
// "mangle": false
|
||||||
|
// }
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
(function f(a) {
|
console.log(function(undefined) {
|
||||||
do {
|
return undefined[function() {
|
||||||
console.log(f.length);
|
{}
|
||||||
} while (console.log(f += 0));
|
}] || 1 + .1 + .1;
|
||||||
})();
|
}(42));
|
||||||
|
|||||||
@@ -1,19 +1,14 @@
|
|||||||
// (beautified)
|
// (beautified)
|
||||||
(function f(a) {
|
console.log(function() {
|
||||||
do {
|
return 1 + .1 + .1;
|
||||||
console.log(f.length);
|
}());
|
||||||
} while (console.log(f += 0));
|
// output: 1.2000000000000002
|
||||||
})();
|
|
||||||
// output: 1
|
|
||||||
// function(){}0
|
|
||||||
//
|
//
|
||||||
// minify: 0
|
// minify: 1.2
|
||||||
// function(){}0
|
|
||||||
//
|
//
|
||||||
// options: {
|
// options: {
|
||||||
// "compress": {
|
// "compress": {
|
||||||
// "keep_fargs": false,
|
// "unsafe_math": true
|
||||||
// "unsafe": true
|
|
||||||
// },
|
// },
|
||||||
// "mangle": false
|
// "mangle": false
|
||||||
// }
|
// }
|
||||||
@@ -1,8 +1,5 @@
|
|||||||
console.log(function f(a) {
|
({
|
||||||
({
|
set p(v) {
|
||||||
set p(v) {
|
console.log(+v + .1 + .1);
|
||||||
f++;
|
}
|
||||||
}
|
}).p = 1;
|
||||||
});
|
|
||||||
return f.length;
|
|
||||||
}());
|
|
||||||
|
|||||||
@@ -1,20 +1,16 @@
|
|||||||
// (beautified)
|
// (beautified)
|
||||||
console.log(function f(a) {
|
({
|
||||||
({
|
set p(v) {
|
||||||
set p(v) {
|
console.log(1 + .1 + .1);
|
||||||
f++;
|
}
|
||||||
}
|
}).p = 0;
|
||||||
});
|
// output: 1.2000000000000002
|
||||||
return f.length;
|
|
||||||
}());
|
|
||||||
// output: 1
|
|
||||||
//
|
//
|
||||||
// minify: 0
|
// minify: 1.2
|
||||||
//
|
//
|
||||||
// options: {
|
// options: {
|
||||||
// "compress": {
|
// "compress": {
|
||||||
// "keep_fargs": false,
|
// "unsafe_math": true
|
||||||
// "unsafe": true
|
|
||||||
// },
|
// },
|
||||||
// "mangle": false
|
// "mangle": false
|
||||||
// }
|
// }
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
var site = "https://browserbench.org/JetStream1.1";
|
var site = "https://browserbench.org/JetStream1.1";
|
||||||
if (typeof phantom == "undefined") {
|
if (typeof phantom == "undefined") {
|
||||||
require("../tools/exit");
|
require("../tools/tty");
|
||||||
var args = process.argv.slice(2);
|
var args = process.argv.slice(2);
|
||||||
var debug = args.indexOf("--debug");
|
var debug = args.indexOf("--debug");
|
||||||
if (debug < 0) {
|
if (debug < 0) {
|
||||||
|
|||||||
65
test/mocha/async.js
Normal file
65
test/mocha/async.js
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
var assert = require("assert");
|
||||||
|
var UglifyJS = require("../node");
|
||||||
|
|
||||||
|
describe("async", function() {
|
||||||
|
it("Should reject `await` as symbol name within async functions only", function() {
|
||||||
|
[
|
||||||
|
"function await() {}",
|
||||||
|
"function(await) {}",
|
||||||
|
"function() { await; }",
|
||||||
|
"function() { await:{} }",
|
||||||
|
"function() { var await; }",
|
||||||
|
"function() { function await() {} }",
|
||||||
|
"function() { try {} catch (await) {} }",
|
||||||
|
].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("(async " + code + ")();");
|
||||||
|
}, function(e) {
|
||||||
|
return e instanceof UglifyJS.JS_Parse_Error;
|
||||||
|
}, code);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should reject `await` expression outside of async functions", function() {
|
||||||
|
[
|
||||||
|
"await 42;",
|
||||||
|
"function f() { await 42; }",
|
||||||
|
"async function f() { function g() { await 42; } }",
|
||||||
|
].forEach(function(code) {
|
||||||
|
assert.throws(function() {
|
||||||
|
UglifyJS.parse(code);
|
||||||
|
}, function(e) {
|
||||||
|
return e instanceof UglifyJS.JS_Parse_Error;
|
||||||
|
}, code);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should reject `await` expression directly on computed key of function argument", function() {
|
||||||
|
[
|
||||||
|
"function f({ [await 42]: a }) {}",
|
||||||
|
"async function f({ [await 42]: a }) {}",
|
||||||
|
].forEach(function(code) {
|
||||||
|
assert.throws(function() {
|
||||||
|
UglifyJS.parse(code);
|
||||||
|
}, function(e) {
|
||||||
|
return e instanceof UglifyJS.JS_Parse_Error;
|
||||||
|
}, code);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should accept `await` expression nested within computed key of function argument", function() {
|
||||||
|
[
|
||||||
|
"function f({ [async function() { await 42; }()]: a }) {}",
|
||||||
|
"async function f({ [async function() { await 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");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
40
test/mocha/bug-report.js
Normal file
40
test/mocha/bug-report.js
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
var assert = require("assert");
|
||||||
|
var exec = require("child_process").exec;
|
||||||
|
|
||||||
|
describe("UGLIFY_BUG_REPORT", function() {
|
||||||
|
var env = Object.create(process.env);
|
||||||
|
env.UGLIFY_BUG_REPORT = 1;
|
||||||
|
it("Should generate bug report via API", function(done) {
|
||||||
|
exec('"' + process.argv[0] + '"', { env: env }, function(err, stdout) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(stdout, [
|
||||||
|
"// UGLIFY_BUG_REPORT",
|
||||||
|
"// <<undefined>>",
|
||||||
|
"",
|
||||||
|
"//-------------------------------------------------------------",
|
||||||
|
"// INPUT CODE",
|
||||||
|
"...---...",
|
||||||
|
"",
|
||||||
|
].join("\n"));
|
||||||
|
done();
|
||||||
|
}).stdin.end('console.log(require("./").minify("...---...").code);');
|
||||||
|
});
|
||||||
|
it("Should generate bug report via CLI", function(done) {
|
||||||
|
exec('"' + process.argv[0] + '" bin/uglifyjs -mc', { env: env }, function(err, stdout) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(stdout, [
|
||||||
|
"// UGLIFY_BUG_REPORT",
|
||||||
|
"// {",
|
||||||
|
'// "mangle": {},',
|
||||||
|
'// "compress": {}',
|
||||||
|
"// }",
|
||||||
|
"",
|
||||||
|
"//-------------------------------------------------------------",
|
||||||
|
"// STDIN",
|
||||||
|
"...---...",
|
||||||
|
"",
|
||||||
|
].join("\n"));
|
||||||
|
done();
|
||||||
|
}).stdin.end("...---...");
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -56,7 +56,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
"--source-map", [
|
"--source-map", [
|
||||||
"names=true",
|
"names=true",
|
||||||
"url=inline",
|
"url=inline",
|
||||||
].join(","),
|
].join(),
|
||||||
].join(" "), function(err, stdout) {
|
].join(" "), function(err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
var expected = [
|
var expected = [
|
||||||
@@ -84,7 +84,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
"--source-map", [
|
"--source-map", [
|
||||||
"names=false",
|
"names=false",
|
||||||
"url=inline",
|
"url=inline",
|
||||||
].join(","),
|
].join(),
|
||||||
].join(" "), function(err, stdout) {
|
].join(" "), function(err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
var expected = [
|
var expected = [
|
||||||
@@ -171,7 +171,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
"content=" + mapFile,
|
"content=" + mapFile,
|
||||||
"includeSources",
|
"includeSources",
|
||||||
"url=inline",
|
"url=inline",
|
||||||
].join(","),
|
].join(),
|
||||||
].join(" ");
|
].join(" ");
|
||||||
|
|
||||||
var child = exec(command, function(err, stdout) {
|
var child = exec(command, function(err, stdout) {
|
||||||
@@ -573,6 +573,20 @@ describe("bin/uglifyjs", function() {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
it("Should throw syntax error (var { eval })", function(done) {
|
||||||
|
var command = uglifyjscmd + " test/input/invalid/destructured_var.js";
|
||||||
|
exec(command, function(err, stdout, stderr) {
|
||||||
|
assert.ok(err);
|
||||||
|
assert.strictEqual(stdout, "");
|
||||||
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
|
"Parse error at test/input/invalid/destructured_var.js:7,10",
|
||||||
|
" var { eval } = 42;",
|
||||||
|
" ^",
|
||||||
|
"ERROR: Unexpected eval in strict mode"
|
||||||
|
].join("\n"));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
it("Should throw syntax error (else)", function(done) {
|
it("Should throw syntax error (else)", function(done) {
|
||||||
var command = uglifyjscmd + " test/input/invalid/else.js";
|
var command = uglifyjscmd + " test/input/invalid/else.js";
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ var UglifyJS = require("../node");
|
|||||||
|
|
||||||
describe("Getters and setters", function() {
|
describe("Getters and setters", function() {
|
||||||
it("Should not accept operator symbols as getter/setter name", function() {
|
it("Should not accept operator symbols as getter/setter name", function() {
|
||||||
var illegalOperators = [
|
[
|
||||||
"++",
|
"++",
|
||||||
"--",
|
"--",
|
||||||
"+",
|
"+",
|
||||||
@@ -42,43 +42,26 @@ describe("Getters and setters", function() {
|
|||||||
"&=",
|
"&=",
|
||||||
"&&",
|
"&&",
|
||||||
"||"
|
"||"
|
||||||
];
|
].reduce(function(tests, illegalOperator) {
|
||||||
var generator = function() {
|
tests.push({
|
||||||
var results = [];
|
code: "var obj = { get " + illegalOperator + "() { return test; }};",
|
||||||
|
operator: illegalOperator,
|
||||||
for (var i in illegalOperators) {
|
});
|
||||||
results.push({
|
tests.push({
|
||||||
code: "var obj = { get " + illegalOperators[i] + "() { return test; }};",
|
code: "var obj = { set " + illegalOperator + "(value) { test = value; }};",
|
||||||
operator: illegalOperators[i],
|
operator: illegalOperator,
|
||||||
method: "get"
|
});
|
||||||
});
|
return tests;
|
||||||
results.push({
|
}, []).forEach(function(test) {
|
||||||
code: "var obj = { set " + illegalOperators[i] + "(value) { test = value}};",
|
assert.throws(function() {
|
||||||
operator: illegalOperators[i],
|
UglifyJS.parse(test.code);
|
||||||
method: "set"
|
}, test.operator == "=" ? function(e) {
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return results;
|
|
||||||
};
|
|
||||||
var testCase = function(data) {
|
|
||||||
return function() {
|
|
||||||
UglifyJS.parse(data.code);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
var fail = function(data) {
|
|
||||||
return function(e) {
|
|
||||||
return e instanceof UglifyJS.JS_Parse_Error
|
return e instanceof UglifyJS.JS_Parse_Error
|
||||||
&& e.message === "Unexpected token: operator «" + data.operator + "»";
|
&& /^Unexpected token: punc «{», expected: punc «.*?»$/.test(e.message);
|
||||||
};
|
} : function(e) {
|
||||||
};
|
return e instanceof UglifyJS.JS_Parse_Error
|
||||||
var errorMessage = function(data) {
|
&& e.message === "Unexpected token: operator «" + test.operator + "»";
|
||||||
return "Expected but didn't get a syntax error while parsing following line:\n" + data.code;
|
}, "Expected but didn't get a syntax error while parsing following line:\n" + test.code);
|
||||||
};
|
});
|
||||||
var tests = generator();
|
|
||||||
for (var i = 0; i < tests.length; i++) {
|
|
||||||
var test = tests[i];
|
|
||||||
assert.throws(testCase(test), fail(test), errorMessage(test));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -89,4 +89,13 @@ describe("Number literals", function() {
|
|||||||
}, code);
|
}, code);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
it("Should reject invalid syntax under expression=true", function() {
|
||||||
|
assert.throws(function() {
|
||||||
|
UglifyJS.parse("42.g", {
|
||||||
|
expression: true,
|
||||||
|
});
|
||||||
|
}, function(e) {
|
||||||
|
return e instanceof UglifyJS.JS_Parse_Error;
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -37,8 +37,7 @@ describe("test/reduce.js", function() {
|
|||||||
it("Should retain setter arguments", function() {
|
it("Should retain setter arguments", function() {
|
||||||
var result = reduce_test(read("test/input/reduce/setter.js"), {
|
var result = reduce_test(read("test/input/reduce/setter.js"), {
|
||||||
compress: {
|
compress: {
|
||||||
keep_fargs: false,
|
unsafe_math: true,
|
||||||
unsafe: true,
|
|
||||||
},
|
},
|
||||||
mangle: false,
|
mangle: false,
|
||||||
}, {
|
}, {
|
||||||
@@ -110,28 +109,24 @@ describe("test/reduce.js", function() {
|
|||||||
});
|
});
|
||||||
it("Should print correct output for irreducible test case", function() {
|
it("Should print correct output for irreducible test case", function() {
|
||||||
var result = reduce_test([
|
var result = reduce_test([
|
||||||
"console.log(function f(a) {",
|
"console.log(1 + .1 + .1);",
|
||||||
" return f.length;",
|
|
||||||
"}());",
|
|
||||||
].join("\n"), {
|
].join("\n"), {
|
||||||
compress: {
|
compress: {
|
||||||
keep_fargs: false,
|
unsafe_math: true,
|
||||||
},
|
},
|
||||||
mangle: false,
|
mangle: false,
|
||||||
});
|
});
|
||||||
if (result.error) throw result.error;
|
if (result.error) throw result.error;
|
||||||
assert.strictEqual(result.code, [
|
assert.strictEqual(result.code, [
|
||||||
"// (beautified)",
|
"// (beautified)",
|
||||||
"console.log(function f(a) {",
|
"console.log(1 + .1 + .1);",
|
||||||
" return f.length;",
|
"// output: 1.2000000000000002",
|
||||||
"}());",
|
|
||||||
"// output: 1",
|
|
||||||
"// ",
|
"// ",
|
||||||
"// minify: 0",
|
"// minify: 1.2",
|
||||||
"// ",
|
"// ",
|
||||||
"// options: {",
|
"// options: {",
|
||||||
'// "compress": {',
|
'// "compress": {',
|
||||||
'// "keep_fargs": false',
|
'// "unsafe_math": true',
|
||||||
"// },",
|
"// },",
|
||||||
'// "mangle": false',
|
'// "mangle": false',
|
||||||
"// }",
|
"// }",
|
||||||
@@ -303,8 +298,7 @@ describe("test/reduce.js", 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"), {
|
||||||
compress: {
|
compress: {
|
||||||
keep_fargs: false,
|
unsafe_math: true,
|
||||||
unsafe: true,
|
|
||||||
},
|
},
|
||||||
mangle: false,
|
mangle: false,
|
||||||
}, {
|
}, {
|
||||||
@@ -313,4 +307,24 @@ 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/diff_error.reduced.js"));
|
assert.strictEqual(result.code, read("test/input/reduce/diff_error.reduced.js"));
|
||||||
});
|
});
|
||||||
|
it("Should maintain valid LHS in destructuring assignments", function() {
|
||||||
|
if (semver.satisfies(process.version, "<6")) return;
|
||||||
|
var result = reduce_test(read("test/input/reduce/destructured_assign.js"), {
|
||||||
|
compress: {
|
||||||
|
unsafe_math: true,
|
||||||
|
},
|
||||||
|
mangle: false,
|
||||||
|
validate: true,
|
||||||
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
assert.strictEqual(result.code, read("test/input/reduce/destructured_assign.reduced.js"));
|
||||||
|
});
|
||||||
|
it("Should handle destructured catch expressions", function() {
|
||||||
|
if (semver.satisfies(process.version, "<6")) return;
|
||||||
|
var result = reduce_test(read("test/input/reduce/destructured_catch.js"), {
|
||||||
|
mangle: false,
|
||||||
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
assert.strictEqual(result.code, read("test/input/reduce/destructured_catch.reduced.js"));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -244,6 +244,39 @@ describe("sourcemaps", function() {
|
|||||||
assert.strictEqual(result.code, '(function(){console.log("hello")}).call(this);');
|
assert.strictEqual(result.code, '(function(){console.log("hello")}).call(this);');
|
||||||
assert.strictEqual(result.map, '{"version":3,"sources":["main.coffee"],"names":["console","log"],"mappings":"CAAA,WAAAA,QAAQC,IAAI"}');
|
assert.strictEqual(result.map, '{"version":3,"sources":["main.coffee"],"names":["console","log"],"mappings":"CAAA,WAAAA,QAAQC,IAAI"}');
|
||||||
});
|
});
|
||||||
|
it("Should not overwrite existing sourcesContent", function() {
|
||||||
|
var result = UglifyJS.minify({
|
||||||
|
"in.js": [
|
||||||
|
'"use strict";',
|
||||||
|
"",
|
||||||
|
"var _window$foo = window.foo,",
|
||||||
|
" a = _window$foo[0],",
|
||||||
|
" b = _window$foo[1];",
|
||||||
|
].join("\n"),
|
||||||
|
}, {
|
||||||
|
compress: false,
|
||||||
|
mangle: false,
|
||||||
|
sourceMap: {
|
||||||
|
content: {
|
||||||
|
version: 3,
|
||||||
|
sources: [ "in.js" ],
|
||||||
|
names: [
|
||||||
|
"window",
|
||||||
|
"foo",
|
||||||
|
"a",
|
||||||
|
"b",
|
||||||
|
],
|
||||||
|
mappings: ";;kBAAaA,MAAM,CAACC,G;IAAfC,C;IAAGC,C",
|
||||||
|
file: "in.js",
|
||||||
|
sourcesContent: [ "let [a, b] = window.foo;\n" ],
|
||||||
|
},
|
||||||
|
includeSources: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
assert.strictEqual(result.code, '"use strict";var _window$foo=window.foo,a=_window$foo[0],b=_window$foo[1];');
|
||||||
|
assert.strictEqual(result.map, '{"version":3,"sources":["in.js"],"sourcesContent":["let [a, b] = window.foo;\\n"],"names":["window","foo","a","b"],"mappings":"6BAAaA,OAAOC,IAAfC,E,eAAGC,E"}');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("sourceMapInline", function() {
|
describe("sourceMapInline", function() {
|
||||||
|
|||||||
139
test/reduce.js
139
test/reduce.js
@@ -18,9 +18,18 @@ var sandbox = require("./sandbox");
|
|||||||
|
|
||||||
Error.stackTraceLimit = Infinity;
|
Error.stackTraceLimit = Infinity;
|
||||||
module.exports = function reduce_test(testcase, minify_options, reduce_options) {
|
module.exports = function reduce_test(testcase, minify_options, reduce_options) {
|
||||||
if (testcase instanceof U.AST_Node) testcase = testcase.print_to_string();
|
|
||||||
minify_options = minify_options || {};
|
minify_options = minify_options || {};
|
||||||
reduce_options = reduce_options || {};
|
reduce_options = reduce_options || {};
|
||||||
|
var print_options = {};
|
||||||
|
[
|
||||||
|
"ie8",
|
||||||
|
"v8",
|
||||||
|
"webkit",
|
||||||
|
].forEach(function(name) {
|
||||||
|
var value = minify_options[name] || minify_options.output && minify_options.output[name];
|
||||||
|
if (value) print_options[name] = value;
|
||||||
|
});
|
||||||
|
if (testcase instanceof U.AST_Node) testcase = testcase.print_to_string(print_options);
|
||||||
var max_iterations = reduce_options.max_iterations || 1000;
|
var max_iterations = reduce_options.max_iterations || 1000;
|
||||||
var max_timeout = reduce_options.max_timeout || 10000;
|
var max_timeout = reduce_options.max_timeout || 10000;
|
||||||
var warnings = [];
|
var warnings = [];
|
||||||
@@ -61,8 +70,8 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
} else if (differs.error) {
|
} else if (differs.error) {
|
||||||
differs.warnings = warnings;
|
differs.warnings = warnings;
|
||||||
return differs;
|
return differs;
|
||||||
} else if (is_error(differs.unminified_result)
|
} else if (sandbox.is_error(differs.unminified_result)
|
||||||
&& is_error(differs.minified_result)
|
&& sandbox.is_error(differs.minified_result)
|
||||||
&& differs.unminified_result.name == differs.minified_result.name) {
|
&& differs.unminified_result.name == differs.minified_result.name) {
|
||||||
return {
|
return {
|
||||||
code: [
|
code: [
|
||||||
@@ -95,15 +104,14 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
|
|
||||||
// quick ignores
|
// quick ignores
|
||||||
if (node instanceof U.AST_Accessor) return;
|
if (node instanceof U.AST_Accessor) return;
|
||||||
if (node instanceof U.AST_Destructured) return;
|
|
||||||
if (node instanceof U.AST_Directive) return;
|
if (node instanceof U.AST_Directive) return;
|
||||||
if (!in_list && node instanceof U.AST_EmptyStatement) return;
|
if (!in_list && node instanceof U.AST_EmptyStatement) return;
|
||||||
if (node instanceof U.AST_Label) return;
|
if (node instanceof U.AST_Label) return;
|
||||||
if (node instanceof U.AST_LabelRef) return;
|
if (node instanceof U.AST_LabelRef) return;
|
||||||
if (!in_list && node instanceof U.AST_SymbolDeclaration) return;
|
|
||||||
if (node instanceof U.AST_Toplevel) return;
|
if (node instanceof U.AST_Toplevel) return;
|
||||||
var parent = tt.parent();
|
var parent = tt.parent();
|
||||||
if (node instanceof U.AST_SymbolFunarg && parent instanceof U.AST_Accessor) return;
|
if (node instanceof U.AST_SymbolFunarg && parent instanceof U.AST_Accessor) return;
|
||||||
|
if (!in_list && parent.rest !== node && node instanceof U.AST_SymbolDeclaration) return;
|
||||||
|
|
||||||
// ensure that the _permute prop is a number.
|
// ensure that the _permute prop is a number.
|
||||||
// can not use `node.start._permute |= 0;` as it will erase fractional part.
|
// can not use `node.start._permute |= 0;` as it will erase fractional part.
|
||||||
@@ -115,7 +123,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
|
|
||||||
// ignore lvalues
|
// ignore lvalues
|
||||||
if (parent instanceof U.AST_Assign && parent.left === node) return;
|
if (parent instanceof U.AST_Assign && parent.left === node) return;
|
||||||
if (parent instanceof U.AST_DestructuredArray) return;
|
if (parent instanceof U.AST_DefaultValue && parent.name === node) return;
|
||||||
if (parent instanceof U.AST_DestructuredKeyVal && parent.value === node) return;
|
if (parent instanceof U.AST_DestructuredKeyVal && parent.value === node) return;
|
||||||
if (parent instanceof U.AST_Unary && parent.expression === node) switch (parent.operator) {
|
if (parent instanceof U.AST_Unary && parent.expression === node) switch (parent.operator) {
|
||||||
case "++":
|
case "++":
|
||||||
@@ -135,7 +143,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
if (expr && !(expr instanceof U.AST_Hole)) {
|
if (expr && !(expr instanceof U.AST_Hole)) {
|
||||||
node.start._permute++;
|
node.start._permute++;
|
||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
return expr;
|
return expr instanceof U.AST_Spread ? expr.expression : expr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (node instanceof U.AST_Binary) {
|
else if (node instanceof U.AST_Binary) {
|
||||||
@@ -144,6 +152,20 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
node.left,
|
node.left,
|
||||||
node.right,
|
node.right,
|
||||||
][ permute & 1 ];
|
][ permute & 1 ];
|
||||||
|
if (expr instanceof U.AST_Destructured) expr = expr.transform(new U.TreeTransformer(function(node, descend) {
|
||||||
|
if (node instanceof U.AST_DefaultValue) return new U.AST_Assign({
|
||||||
|
operator: "=",
|
||||||
|
left: node.name.transform(this),
|
||||||
|
right: node.value,
|
||||||
|
start: {},
|
||||||
|
});
|
||||||
|
if (node instanceof U.AST_DestructuredKeyVal) return new U.AST_ObjectKeyVal(node);
|
||||||
|
if (node instanceof U.AST_Destructured) {
|
||||||
|
node = new (node instanceof U.AST_DestructuredArray ? U.AST_Array : U.AST_Object)(node);
|
||||||
|
descend(node, this);
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}));
|
||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
return permute < 2 ? expr : wrap_with_console_log(expr);
|
return permute < 2 ? expr : wrap_with_console_log(expr);
|
||||||
}
|
}
|
||||||
@@ -164,7 +186,13 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
][ ((node.start._permute += step) * steps | 0) % 3 ];
|
][ ((node.start._permute += step) * steps | 0) % 3 ];
|
||||||
if (expr) {
|
if (expr) {
|
||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
return expr;
|
return expr instanceof U.AST_Spread ? expr.expression : expr;
|
||||||
|
}
|
||||||
|
if (node.expression instanceof U.AST_Arrow && node.expression.value) {
|
||||||
|
var seq = node.args.slice();
|
||||||
|
seq.push(node.expression.value);
|
||||||
|
CHANGED = true;
|
||||||
|
return to_sequence(seq);
|
||||||
}
|
}
|
||||||
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
|
||||||
@@ -196,6 +224,28 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
node.alternative,
|
node.alternative,
|
||||||
][ ((node.start._permute += step) * steps | 0) % 3 ];
|
][ ((node.start._permute += step) * steps | 0) % 3 ];
|
||||||
}
|
}
|
||||||
|
else if (node instanceof U.AST_DefaultValue) {
|
||||||
|
node.start._permute++;
|
||||||
|
CHANGED = true;
|
||||||
|
return node.name;
|
||||||
|
}
|
||||||
|
else if (node instanceof U.AST_DestructuredArray) {
|
||||||
|
var expr = node.elements[0];
|
||||||
|
if (expr && !(expr instanceof U.AST_Hole)) {
|
||||||
|
node.start._permute++;
|
||||||
|
CHANGED = true;
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (node instanceof U.AST_DestructuredObject) {
|
||||||
|
// first property's value
|
||||||
|
var expr = node.properties[0];
|
||||||
|
if (expr) {
|
||||||
|
node.start._permute++;
|
||||||
|
CHANGED = true;
|
||||||
|
return expr.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (node instanceof U.AST_Defun) {
|
else if (node instanceof U.AST_Defun) {
|
||||||
switch (((node.start._permute += step) * steps | 0) % 2) {
|
switch (((node.start._permute += step) * steps | 0) % 2) {
|
||||||
case 0:
|
case 0:
|
||||||
@@ -289,7 +339,16 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
}
|
}
|
||||||
else if (node instanceof U.AST_Object) {
|
else if (node instanceof U.AST_Object) {
|
||||||
// first property's value
|
// first property's value
|
||||||
var expr = node.properties[0] instanceof U.AST_ObjectKeyVal && node.properties[0].value;
|
var expr = node.properties[0];
|
||||||
|
if (expr instanceof U.AST_ObjectKeyVal) {
|
||||||
|
expr = expr.value;
|
||||||
|
} else if (expr instanceof U.AST_Spread) {
|
||||||
|
expr = expr.expression;
|
||||||
|
} else if (expr && expr.key instanceof U.AST_Node) {
|
||||||
|
expr = expr.key;
|
||||||
|
} else {
|
||||||
|
expr = null;
|
||||||
|
}
|
||||||
if (expr) {
|
if (expr) {
|
||||||
node.start._permute++;
|
node.start._permute++;
|
||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
@@ -299,7 +358,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,
|
||||||
node.property instanceof U.AST_Node && 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) {
|
||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
@@ -381,9 +440,8 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (in_list) {
|
if (in_list) {
|
||||||
// special case to drop object properties and switch branches
|
// drop switch branches
|
||||||
if (parent instanceof U.AST_Object
|
if (parent instanceof U.AST_Switch && parent.expression != node) {
|
||||||
|| parent instanceof U.AST_Switch && parent.expression != node) {
|
|
||||||
node.start._permute++;
|
node.start._permute++;
|
||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
return List.skip;
|
return List.skip;
|
||||||
@@ -402,13 +460,10 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
return List.skip;
|
return List.skip;
|
||||||
}
|
}
|
||||||
|
} else if (parent.rest === node) {
|
||||||
// skip element/property from (destructured) array/object
|
node.start._permute++;
|
||||||
if (parent instanceof U.AST_Array || parent instanceof U.AST_Destructured || parent instanceof AST_Object) {
|
CHANGED = true;
|
||||||
node.start._permute++;
|
return null;
|
||||||
CHANGED = true;
|
|
||||||
return List.skip;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// replace this node
|
// replace this node
|
||||||
@@ -449,7 +504,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
if (node.TYPE == "Call" && node.expression.print_to_string() == "console.log") {
|
if (node.TYPE == "Call" && node.expression.print_to_string() == "console.log") {
|
||||||
return to_sequence(node.args);
|
return to_sequence(node.args);
|
||||||
}
|
}
|
||||||
if (node instanceof U.AST_Catch && node.argname) {
|
if (node instanceof U.AST_Catch && node.argname instanceof U.AST_SymbolCatch) {
|
||||||
descend(node, this);
|
descend(node, this);
|
||||||
node.body.unshift(new U.AST_SimpleStatement({
|
node.body.unshift(new U.AST_SimpleStatement({
|
||||||
body: wrap_with_console_log(new U.AST_SymbolRef(node.argname)),
|
body: wrap_with_console_log(new U.AST_SymbolRef(node.argname)),
|
||||||
@@ -458,7 +513,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
var code = testcase_ast.print_to_string();
|
var code = testcase_ast.print_to_string(print_options);
|
||||||
var diff = test_for_diff(code, minify_options, result_cache, max_timeout);
|
var diff = test_for_diff(code, minify_options, result_cache, max_timeout);
|
||||||
if (diff && !diff.timed_out && !diff.error) {
|
if (diff && !diff.timed_out && !diff.error) {
|
||||||
testcase = code;
|
testcase = code;
|
||||||
@@ -482,7 +537,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
var code_ast = testcase_ast.clone(true).transform(tt);
|
var code_ast = testcase_ast.clone(true).transform(tt);
|
||||||
if (!CHANGED) break;
|
if (!CHANGED) break;
|
||||||
try {
|
try {
|
||||||
var code = code_ast.print_to_string();
|
var code = code_ast.print_to_string(print_options);
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
// AST is not well formed.
|
// AST is not well formed.
|
||||||
// no harm done - just log the error, ignore latest change and continue iterating.
|
// no harm done - just log the error, ignore latest change and continue iterating.
|
||||||
@@ -503,8 +558,8 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
log(code);
|
log(code);
|
||||||
log(diff.error.stack);
|
log(diff.error.stack);
|
||||||
log("*** Discarding permutation and continuing.");
|
log("*** Discarding permutation and continuing.");
|
||||||
} else if (is_error(diff.unminified_result)
|
} else if (sandbox.is_error(diff.unminified_result)
|
||||||
&& is_error(diff.minified_result)
|
&& sandbox.is_error(diff.minified_result)
|
||||||
&& diff.unminified_result.name == diff.minified_result.name) {
|
&& diff.unminified_result.name == diff.minified_result.name) {
|
||||||
// ignore difference in error messages caused by minification
|
// ignore difference in error messages caused by minification
|
||||||
diff_error_message = testcase;
|
diff_error_message = testcase;
|
||||||
@@ -524,11 +579,13 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
var beautified = U.minify(testcase, {
|
var beautified = U.minify(testcase, {
|
||||||
compress: false,
|
compress: false,
|
||||||
mangle: false,
|
mangle: false,
|
||||||
output: {
|
output: function() {
|
||||||
beautify: true,
|
var options = JSON.parse(JSON.stringify(print_options));
|
||||||
braces: true,
|
options.beautify = true;
|
||||||
comments: true,
|
options.braces = true;
|
||||||
},
|
options.comments = true;
|
||||||
|
return options;
|
||||||
|
}(),
|
||||||
});
|
});
|
||||||
testcase = {
|
testcase = {
|
||||||
code: testcase,
|
code: testcase,
|
||||||
@@ -543,10 +600,10 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
}
|
}
|
||||||
var lines = [ "" ];
|
var lines = [ "" ];
|
||||||
if (isNaN(max_timeout)) {
|
if (isNaN(max_timeout)) {
|
||||||
lines.push("// minify error: " + to_comment(strip_color_codes(differs.minified_result.stack)));
|
lines.push("// minify error: " + to_comment(differs.minified_result.stack));
|
||||||
} else {
|
} else {
|
||||||
var unminified_result = strip_color_codes(differs.unminified_result);
|
var unminified_result = differs.unminified_result;
|
||||||
var minified_result = strip_color_codes(differs.minified_result);
|
var minified_result = differs.minified_result;
|
||||||
if (trim_trailing_whitespace(unminified_result) == trim_trailing_whitespace(minified_result)) {
|
if (trim_trailing_whitespace(unminified_result) == trim_trailing_whitespace(minified_result)) {
|
||||||
lines.push(
|
lines.push(
|
||||||
"// (stringified)",
|
"// (stringified)",
|
||||||
@@ -567,10 +624,6 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function strip_color_codes(value) {
|
|
||||||
return ("" + value).replace(/\u001b\[\d+m/g, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
function to_comment(value) {
|
function to_comment(value) {
|
||||||
return ("" + value).replace(/\n/g, "\n// ");
|
return ("" + value).replace(/\n/g, "\n// ");
|
||||||
}
|
}
|
||||||
@@ -608,16 +661,16 @@ function has_loopcontrol(body, loop, label) {
|
|||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
function is_error(result) {
|
|
||||||
return typeof result == "object" && typeof result.name == "string" && typeof result.message == "string";
|
|
||||||
}
|
|
||||||
|
|
||||||
function is_timed_out(result) {
|
function is_timed_out(result) {
|
||||||
return is_error(result) && /timed out/.test(result.message);
|
return sandbox.is_error(result) && /timed out/.test(result.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
function is_statement(node) {
|
function is_statement(node) {
|
||||||
return node instanceof U.AST_Statement && !(node instanceof U.AST_Function);
|
return node instanceof U.AST_Statement
|
||||||
|
&& !(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) {
|
||||||
|
|||||||
332
test/sandbox.js
332
test/sandbox.js
@@ -1,83 +1,39 @@
|
|||||||
|
var readFileSync = require("fs").readFileSync;
|
||||||
var semver = require("semver");
|
var semver = require("semver");
|
||||||
|
var spawnSync = require("child_process").spawnSync;
|
||||||
var vm = require("vm");
|
var vm = require("vm");
|
||||||
|
|
||||||
var setupContext = new vm.Script([
|
setup_log();
|
||||||
"[ Array, Boolean, Error, Function, Number, Object, RegExp, String ].forEach(function(f) {",
|
var setup_code = "(" + setup + ")(" + [
|
||||||
" f.toString = Function.prototype.toString;",
|
"this",
|
||||||
"});",
|
find_builtins(),
|
||||||
"Function.prototype.toString = function() {",
|
setup_log,
|
||||||
" var id = 100000;",
|
"function(process) {" + readFileSync(require.resolve("../tools/tty", "utf8")) + "}",
|
||||||
" return function() {",
|
].join(",\n") + ");\n";
|
||||||
" var n = this.name;",
|
exports.has_toplevel = function(options) {
|
||||||
" if (!/^F[0-9]{6}N$/.test(n)) {",
|
return options.toplevel
|
||||||
' n = "F" + ++id + "N";',
|
|| options.mangle && options.mangle.toplevel
|
||||||
].concat(Object.getOwnPropertyDescriptor(Function.prototype, "name").configurable ? [
|
|| options.compress && options.compress.toplevel;
|
||||||
' Object.defineProperty(this, "name", {',
|
};
|
||||||
" get: function() {",
|
exports.is_error = is_error;
|
||||||
" return n;",
|
exports.run_code = semver.satisfies(process.version, "0.8") ? function(code, toplevel, timeout) {
|
||||||
" }",
|
var stdout = run_code_vm(code, toplevel, timeout);
|
||||||
" });",
|
if (typeof stdout != "string" || !/arguments/.test(code)) return stdout;
|
||||||
] : [], [
|
do {
|
||||||
" }",
|
var prev = stdout;
|
||||||
' return "function(){}";',
|
stdout = run_code_vm(code, toplevel, timeout);
|
||||||
" };",
|
} while (prev !== stdout);
|
||||||
"}();",
|
return stdout;
|
||||||
"this;",
|
} : semver.satisfies(process.version, "<0.12") ? run_code_vm : function(code, toplevel, timeout) {
|
||||||
]).join("\n"));
|
if (/\basync([ \t]+[^\s()[\]{},.&|!~=*%/+-]+|[ \t]*\([\s\S]*?\))[ \t]*=>|\b(async[ \t]+function|setInterval|setTimeout)\b/.test(code)) {
|
||||||
|
return run_code_exec(code, toplevel, timeout);
|
||||||
function createContext() {
|
} else {
|
||||||
var ctx = vm.createContext(Object.defineProperty({}, "console", { value: { log: log } }));
|
return run_code_vm(code, toplevel, timeout);
|
||||||
var global = setupContext.runInContext(ctx);
|
|
||||||
return ctx;
|
|
||||||
|
|
||||||
function safe_log(arg, level) {
|
|
||||||
if (arg) switch (typeof arg) {
|
|
||||||
case "function":
|
|
||||||
return arg.toString();
|
|
||||||
case "object":
|
|
||||||
if (arg === global) return "[object global]";
|
|
||||||
if (/Error$/.test(arg.name)) return arg.toString();
|
|
||||||
arg.constructor.toString();
|
|
||||||
if (level--) for (var key in arg) {
|
|
||||||
var desc = Object.getOwnPropertyDescriptor(arg, key);
|
|
||||||
if (!desc || !desc.get && !desc.set) arg[key] = safe_log(arg[key], level);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return arg;
|
|
||||||
}
|
|
||||||
|
|
||||||
function log(msg) {
|
|
||||||
if (arguments.length == 1 && typeof msg == "string") return console.log("%s", msg);
|
|
||||||
return console.log.apply(console, [].map.call(arguments, function(arg) {
|
|
||||||
return safe_log(arg, 3);
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.run_code = function(code, toplevel, timeout) {
|
|
||||||
timeout = timeout || 5000;
|
|
||||||
var stdout = "";
|
|
||||||
var original_write = process.stdout.write;
|
|
||||||
process.stdout.write = function(chunk) {
|
|
||||||
stdout += chunk;
|
|
||||||
};
|
|
||||||
try {
|
|
||||||
vm.runInContext(toplevel ? "(function(){" + code + "})()" : code, createContext(), { timeout: timeout });
|
|
||||||
return stdout;
|
|
||||||
} catch (ex) {
|
|
||||||
return ex;
|
|
||||||
} finally {
|
|
||||||
process.stdout.write = original_write;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function strip_func_ids(text) {
|
|
||||||
return ("" + text).replace(/F[0-9]{6}N/g, "<F<>N>");
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.same_stdout = semver.satisfies(process.version, "0.12") ? function(expected, actual) {
|
exports.same_stdout = semver.satisfies(process.version, "0.12") ? function(expected, actual) {
|
||||||
if (typeof expected != typeof actual) return false;
|
if (typeof expected != typeof actual) return false;
|
||||||
if (typeof expected == "object" && typeof expected.name == "string" && typeof expected.message == "string") {
|
if (is_error(expected)) {
|
||||||
if (expected.name !== actual.name) return false;
|
if (expected.name !== actual.name) return false;
|
||||||
if (typeof actual.message != "string") return false;
|
if (typeof actual.message != "string") return false;
|
||||||
expected = expected.message.slice(expected.message.lastIndexOf("\n") + 1);
|
expected = expected.message.slice(expected.message.lastIndexOf("\n") + 1);
|
||||||
@@ -87,8 +43,228 @@ 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.has_toplevel = function(options) {
|
|
||||||
return options.toplevel
|
function is_error(result) {
|
||||||
|| options.mangle && options.mangle.toplevel
|
return result && typeof result.name == "string" && typeof result.message == "string";
|
||||||
|| options.compress && options.compress.toplevel;
|
}
|
||||||
};
|
|
||||||
|
function strip_color_codes(value) {
|
||||||
|
return value.replace(/\u001b\[\d+m/g, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
function strip_func_ids(text) {
|
||||||
|
return ("" + text).replace(/F[0-9]{6}N/g, "<F<>N>");
|
||||||
|
}
|
||||||
|
|
||||||
|
function setup_log() {
|
||||||
|
var inspect = require("util").inspect;
|
||||||
|
if (inspect.defaultOptions) {
|
||||||
|
var log_options = {
|
||||||
|
breakLength: Infinity,
|
||||||
|
colors: false,
|
||||||
|
compact: true,
|
||||||
|
customInspect: false,
|
||||||
|
depth: Infinity,
|
||||||
|
maxArrayLength: Infinity,
|
||||||
|
maxStringLength: Infinity,
|
||||||
|
showHidden: false,
|
||||||
|
};
|
||||||
|
for (var name in log_options) {
|
||||||
|
if (name in inspect.defaultOptions) inspect.defaultOptions[name] = log_options[name];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return inspect;
|
||||||
|
}
|
||||||
|
|
||||||
|
function find_builtins() {
|
||||||
|
setup_code = "console.log(Object.keys(this));";
|
||||||
|
var builtins = run_code_vm("");
|
||||||
|
if (semver.satisfies(process.version, ">=0.12")) builtins += ".concat(" + run_code_exec("") + ")";
|
||||||
|
return builtins;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setup(global, builtins, setup_log, setup_tty) {
|
||||||
|
[ Array, Boolean, Error, Function, Number, Object, RegExp, String ].forEach(function(f) {
|
||||||
|
f.toString = Function.prototype.toString;
|
||||||
|
});
|
||||||
|
Function.prototype.toString = function() {
|
||||||
|
var configurable = Object.getOwnPropertyDescriptor(Function.prototype, "name").configurable;
|
||||||
|
var id = 100000;
|
||||||
|
return function() {
|
||||||
|
var n = this.name;
|
||||||
|
if (!/^F[0-9]{6}N$/.test(n)) {
|
||||||
|
n = "F" + ++id + "N";
|
||||||
|
if (configurable) Object.defineProperty(this, "name", {
|
||||||
|
get: function() {
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return "function(){}";
|
||||||
|
};
|
||||||
|
}();
|
||||||
|
var process = global.process;
|
||||||
|
if (process) {
|
||||||
|
setup_tty(process);
|
||||||
|
var inspect = setup_log();
|
||||||
|
process.on("uncaughtException", function(ex) {
|
||||||
|
var value = ex;
|
||||||
|
if (value instanceof Error) {
|
||||||
|
value = {};
|
||||||
|
for (var name in ex) {
|
||||||
|
value[name] = ex[name];
|
||||||
|
delete ex[name];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
process.stderr.write(inspect(value) + "\n\n-----===== UNCAUGHT EXCEPTION =====-----\n\n");
|
||||||
|
throw ex;
|
||||||
|
}).on("unhandledRejection", function() {});
|
||||||
|
}
|
||||||
|
var log = console.log;
|
||||||
|
var safe_console = {
|
||||||
|
log: function(msg) {
|
||||||
|
if (arguments.length == 1 && typeof msg == "string") return log("%s", msg);
|
||||||
|
return log.apply(null, [].map.call(arguments, function(arg) {
|
||||||
|
return safe_log(arg, {
|
||||||
|
level: 5,
|
||||||
|
original: [],
|
||||||
|
replaced: [],
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
};
|
||||||
|
var props = {
|
||||||
|
// for Node.js v8
|
||||||
|
console: {
|
||||||
|
get: function() {
|
||||||
|
return safe_console;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
global: { get: self },
|
||||||
|
self: { get: self },
|
||||||
|
window: { get: self },
|
||||||
|
};
|
||||||
|
[
|
||||||
|
// for Node.js v0.12
|
||||||
|
"Buffer",
|
||||||
|
"clearInterval",
|
||||||
|
"clearTimeout",
|
||||||
|
// for Node.js v0.12
|
||||||
|
"DTRACE_NET_STREAM_END",
|
||||||
|
// for Node.js v8
|
||||||
|
"process",
|
||||||
|
"setInterval",
|
||||||
|
"setTimeout",
|
||||||
|
].forEach(function(name) {
|
||||||
|
var value = global[name];
|
||||||
|
props[name] = {
|
||||||
|
get: function() {
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
builtins.forEach(function(name) {
|
||||||
|
try {
|
||||||
|
delete global[name];
|
||||||
|
} catch (e) {}
|
||||||
|
});
|
||||||
|
Object.defineProperties(global, props);
|
||||||
|
// for Node.js v8+
|
||||||
|
global.toString = function() {
|
||||||
|
return "[object global]";
|
||||||
|
};
|
||||||
|
|
||||||
|
function self() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
function safe_log(arg, cache) {
|
||||||
|
if (arg) switch (typeof arg) {
|
||||||
|
case "function":
|
||||||
|
return arg.toString();
|
||||||
|
case "object":
|
||||||
|
if (arg === global) return "[object global]";
|
||||||
|
if (/Error$/.test(arg.name)) return arg.toString();
|
||||||
|
if (typeof arg.then == "function") return "[object Promise]";
|
||||||
|
arg.constructor.toString();
|
||||||
|
var index = cache.original.indexOf(arg);
|
||||||
|
if (index >= 0) return cache.replaced[index];
|
||||||
|
if (--cache.level < 0) return "[object Object]";
|
||||||
|
var value = {};
|
||||||
|
cache.original.push(arg);
|
||||||
|
cache.replaced.push(value);
|
||||||
|
for (var key in arg) {
|
||||||
|
var desc = Object.getOwnPropertyDescriptor(arg, key);
|
||||||
|
if (desc && (desc.get || desc.set)) {
|
||||||
|
Object.defineProperty(value, key, desc);
|
||||||
|
} else {
|
||||||
|
value[key] = safe_log(arg[key], cache);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return arg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_code_vm(code, toplevel, timeout) {
|
||||||
|
timeout = timeout || 5000;
|
||||||
|
var stdout = "";
|
||||||
|
var original_write = process.stdout.write;
|
||||||
|
process.stdout.write = function(chunk) {
|
||||||
|
stdout += chunk;
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
var ctx = vm.createContext({ console: console });
|
||||||
|
// for Node.js v6
|
||||||
|
vm.runInContext(setup_code, ctx);
|
||||||
|
vm.runInContext(toplevel ? "(function(){" + code + "})();" : code, ctx, { timeout: timeout });
|
||||||
|
return strip_color_codes(stdout);
|
||||||
|
} catch (ex) {
|
||||||
|
return ex;
|
||||||
|
} finally {
|
||||||
|
process.stdout.write = original_write;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_code_exec(code, toplevel, timeout) {
|
||||||
|
if (toplevel) {
|
||||||
|
code = setup_code + "(function(){" + code + "})();";
|
||||||
|
} else {
|
||||||
|
code = code.replace(/^((["'])[^"']*\2(;|$))?/, function(directive) {
|
||||||
|
return directive + setup_code;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
var result = spawnSync(process.argv[0], [ '--max-old-space-size=2048' ], {
|
||||||
|
encoding: "utf8",
|
||||||
|
input: code,
|
||||||
|
stdio: "pipe",
|
||||||
|
timeout: timeout || 5000,
|
||||||
|
});
|
||||||
|
if (result.status === 0) return result.stdout;
|
||||||
|
if (result.error && result.error.code == "ETIMEDOUT" || /FATAL ERROR:/.test(msg)) {
|
||||||
|
return new Error("Script execution timed out.");
|
||||||
|
}
|
||||||
|
if (result.error) return result.error;
|
||||||
|
var msg = result.stderr.replace(/\r\n/g, "\n");
|
||||||
|
var end = msg.indexOf("\n\n-----===== UNCAUGHT EXCEPTION =====-----\n\n");
|
||||||
|
var details;
|
||||||
|
if (end >= 0) {
|
||||||
|
details = msg.slice(0, end).replace(/<([1-9][0-9]*) empty items?>/g, function(match, count) {
|
||||||
|
return new Array(+count).join();
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
details = vm.runInNewContext("(" + details + ")");
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
var match = /\n([^:\s]*Error)(?:: ([\s\S]+?))?\n( at [\s\S]+)\n$/.exec(msg);
|
||||||
|
if (!match) return details;
|
||||||
|
var ex = new global[match[1]](match[2]);
|
||||||
|
ex.stack = ex.stack.slice(0, ex.stack.indexOf(" at ")) + match[3];
|
||||||
|
if (typeof details == "object") {
|
||||||
|
for (var name in details) ex[name] = details[name];
|
||||||
|
} else if (end >= 0) {
|
||||||
|
ex.details = details;
|
||||||
|
}
|
||||||
|
return ex;
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,16 +10,17 @@ exports.init = function(url, auth, num) {
|
|||||||
exports.should_stop = function(callback) {
|
exports.should_stop = function(callback) {
|
||||||
read(base + "/actions/runs?per_page=100", function(reply) {
|
read(base + "/actions/runs?per_page=100", function(reply) {
|
||||||
if (!reply || !Array.isArray(reply.workflow_runs)) return;
|
if (!reply || !Array.isArray(reply.workflow_runs)) return;
|
||||||
var runs = reply.workflow_runs.filter(function(workflow) {
|
var runs = reply.workflow_runs.sort(function(a, b) {
|
||||||
return workflow.status != "completed";
|
|
||||||
}).sort(function(a, b) {
|
|
||||||
return b.run_number - a.run_number;
|
return b.run_number - a.run_number;
|
||||||
});
|
});
|
||||||
var found = false, remaining = 20;
|
var found = false, remaining = 20;
|
||||||
(function next() {
|
(function next() {
|
||||||
if (!runs.length) return;
|
var workflow;
|
||||||
var workflow = runs.pop();
|
do {
|
||||||
if (workflow.event == "schedule" && workflow.run_number == run_number) found = true;
|
workflow = runs.pop();
|
||||||
|
if (!workflow) return;
|
||||||
|
if (workflow.event == "schedule" && workflow.run_number == run_number) found = true;
|
||||||
|
} while (!found && workflow.status == "completed");
|
||||||
read(workflow.jobs_url, function(reply) {
|
read(workflow.jobs_url, function(reply) {
|
||||||
if (!reply || !Array.isArray(reply.jobs)) return;
|
if (!reply || !Array.isArray(reply.jobs)) return;
|
||||||
if (!reply.jobs.every(function(job) {
|
if (!reply.jobs.every(function(job) {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -70,7 +70,7 @@ function run() {
|
|||||||
|
|
||||||
function trap(data) {
|
function trap(data) {
|
||||||
stderr += data;
|
stderr += data;
|
||||||
if (~stderr.indexOf("\nminify(options):\n")) {
|
if (~stderr.indexOf("!!!!!! Failed... round ")) {
|
||||||
process.exitCode = 1;
|
process.exitCode = 1;
|
||||||
child.stderr.removeListener("data", trap);
|
child.stderr.removeListener("data", trap);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,14 +21,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"compress": {
|
"compress": {
|
||||||
|
"hoist_vars": true,
|
||||||
|
"keep_infinity": true,
|
||||||
"passes": 1e6,
|
"passes": 1e6,
|
||||||
"unsafe": true
|
"unsafe": true
|
||||||
},
|
},
|
||||||
|
"keep_fnames": true,
|
||||||
"toplevel": true
|
"toplevel": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"compress": {
|
"compress": {
|
||||||
"keep_fargs": false,
|
|
||||||
"passes": 1e6,
|
"passes": 1e6,
|
||||||
"sequences": 1e6,
|
"sequences": 1e6,
|
||||||
"unsafe": true,
|
"unsafe": true,
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
// workaround for tty output truncation upon process.exit()
|
|
||||||
var exit = process.exit;
|
|
||||||
process.exit = function() {
|
|
||||||
var args = [].slice.call(arguments);
|
|
||||||
process.once("uncaughtException", function() {
|
|
||||||
(function callback() {
|
|
||||||
if (process.stdout.bufferSize || process.stderr.bufferSize) {
|
|
||||||
setTimeout(callback, 1);
|
|
||||||
} else {
|
|
||||||
exit.apply(process, args);
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
});
|
|
||||||
throw exit;
|
|
||||||
};
|
|
||||||
@@ -3,11 +3,11 @@ var fs = require("fs");
|
|||||||
exports.FILES = [
|
exports.FILES = [
|
||||||
require.resolve("../lib/utils.js"),
|
require.resolve("../lib/utils.js"),
|
||||||
require.resolve("../lib/ast.js"),
|
require.resolve("../lib/ast.js"),
|
||||||
require.resolve("../lib/parse.js"),
|
|
||||||
require.resolve("../lib/transform.js"),
|
require.resolve("../lib/transform.js"),
|
||||||
|
require.resolve("../lib/parse.js"),
|
||||||
require.resolve("../lib/scope.js"),
|
require.resolve("../lib/scope.js"),
|
||||||
require.resolve("../lib/output.js"),
|
|
||||||
require.resolve("../lib/compress.js"),
|
require.resolve("../lib/compress.js"),
|
||||||
|
require.resolve("../lib/output.js"),
|
||||||
require.resolve("../lib/sourcemap.js"),
|
require.resolve("../lib/sourcemap.js"),
|
||||||
require.resolve("../lib/mozilla-ast.js"),
|
require.resolve("../lib/mozilla-ast.js"),
|
||||||
require.resolve("../lib/propmangle.js"),
|
require.resolve("../lib/propmangle.js"),
|
||||||
@@ -23,6 +23,37 @@ new Function("exports", function() {
|
|||||||
return code.join("\n\n");
|
return code.join("\n\n");
|
||||||
}())(exports);
|
}())(exports);
|
||||||
|
|
||||||
|
function to_comment(value) {
|
||||||
|
if (typeof value != "string") value = JSON.stringify(value, function(key, value) {
|
||||||
|
return typeof value == "function" ? "<[ " + value + " ]>" : value;
|
||||||
|
}, 2);
|
||||||
|
return "// " + value.replace(/\n/g, "\n// ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (+process.env["UGLIFY_BUG_REPORT"]) exports.minify = function(files, options) {
|
||||||
|
if (typeof options == "undefined") options = "<<undefined>>";
|
||||||
|
var code = [
|
||||||
|
"// UGLIFY_BUG_REPORT",
|
||||||
|
to_comment(options),
|
||||||
|
];
|
||||||
|
if (typeof files == "string") {
|
||||||
|
code.push("");
|
||||||
|
code.push("//-------------------------------------------------------------")
|
||||||
|
code.push("// INPUT CODE", files);
|
||||||
|
} else for (var name in files) {
|
||||||
|
code.push("");
|
||||||
|
code.push("//-------------------------------------------------------------")
|
||||||
|
code.push(to_comment(name), files[name]);
|
||||||
|
}
|
||||||
|
if (options.sourceMap && options.sourceMap.url) {
|
||||||
|
code.push("");
|
||||||
|
code.push("//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9");
|
||||||
|
}
|
||||||
|
var result = { code: code.join("\n") };
|
||||||
|
if (options.sourceMap) result.map = '{"version":3,"sources":[],"names":[],"mappings":""}';
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
function describe_ast() {
|
function describe_ast() {
|
||||||
var out = OutputStream({ beautify: true });
|
var out = OutputStream({ beautify: true });
|
||||||
function doitem(ctor) {
|
function doitem(ctor) {
|
||||||
|
|||||||
22
tools/tty.js
Normal file
22
tools/tty.js
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
// workaround for tty output truncation on Node.js
|
||||||
|
try {
|
||||||
|
// prevent buffer overflow and other asynchronous bugs
|
||||||
|
process.stdout._handle.setBlocking(true);
|
||||||
|
process.stderr._handle.setBlocking(true);
|
||||||
|
} catch (e) {
|
||||||
|
// ensure output buffers are flushed before process termination
|
||||||
|
var exit = process.exit;
|
||||||
|
process.exit = function() {
|
||||||
|
var args = [].slice.call(arguments);
|
||||||
|
process.once("uncaughtException", function() {
|
||||||
|
(function callback() {
|
||||||
|
if (process.stdout.bufferSize || process.stderr.bufferSize) {
|
||||||
|
setTimeout(callback, 1);
|
||||||
|
} else {
|
||||||
|
exit.apply(process, args);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
});
|
||||||
|
throw exit;
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user