Compare commits
112 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
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
|
||||||
|
|||||||
29
.github/workflows/ufuzz.yml
vendored
29
.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,39 @@ 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') }}
|
||||||
|
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
|
||||||
|
|||||||
95
README.md
95
README.md
@@ -135,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.
|
||||||
@@ -522,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.
|
||||||
|
|
||||||
@@ -621,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`
|
||||||
@@ -638,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
|
||||||
@@ -683,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.
|
||||||
@@ -739,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
|
||||||
@@ -753,20 +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();`
|
||||||
|
|
||||||
- `spread` (default: `true`) -- flatten spread expressions.
|
- `spreads` (default: `true`) -- flatten spread expressions.
|
||||||
|
|
||||||
- `strings` (default: `true`) -- compact string concatenations.
|
- `strings` (default: `true`) -- compact string concatenations.
|
||||||
|
|
||||||
- `switches` (default: `true`) -- de-duplicate and remove unreachable `switch` branches
|
- `switches` (default: `true`) -- de-duplicate and remove unreachable `switch` branches
|
||||||
|
|
||||||
- `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.
|
||||||
@@ -803,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"]`.
|
||||||
|
|
||||||
@@ -873,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;
|
||||||
}
|
}
|
||||||
@@ -919,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).
|
||||||
@@ -1146,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 });
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -1178,10 +1182,10 @@ To allow for better optimizations, the compiler makes various assumptions:
|
|||||||
`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:
|
- Earlier versions of JavaScript will throw `SyntaxError` with the following:
|
||||||
```js
|
```javascript
|
||||||
({
|
({
|
||||||
p: 42,
|
p: 42,
|
||||||
get p() {},
|
get p() {},
|
||||||
});
|
});
|
||||||
// SyntaxError: Object literal may not have data and accessor property with
|
// SyntaxError: Object literal may not have data and accessor property with
|
||||||
// the same name
|
// the same name
|
||||||
@@ -1191,7 +1195,7 @@ To allow for better optimizations, the compiler makes various assumptions:
|
|||||||
versions of Chrome and Node.js may be altered.
|
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.
|
||||||
@@ -1209,3 +1213,44 @@ 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.
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
220
lib/ast.js
220
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,13 +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_Hole) throw new Error(prop + " cannot be AST_Hole");
|
if (!(value instanceof AST_Node)) throw new Error(prop + " must " + multiple + " AST_Node");
|
||||||
if (node[prop] instanceof AST_Spread) throw new Error(prop + " cannot be AST_Spread");
|
if (value instanceof AST_DefaultValue) throw new Error(prop + " cannot " + multiple + " AST_DefaultValue");
|
||||||
if (node[prop] instanceof AST_Statement && !is_function(node[prop])) {
|
if (value instanceof AST_Destructured) throw new Error(prop + " cannot " + multiple + " AST_Destructured");
|
||||||
throw new Error(prop + " cannot be AST_Statement");
|
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", {
|
||||||
@@ -502,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;
|
||||||
@@ -520,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;
|
||||||
@@ -528,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);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@@ -535,24 +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);
|
||||||
|
|
||||||
function is_function(node) {
|
function is_arrow(node) {
|
||||||
return node instanceof AST_AsyncFunction || node instanceof AST_Function;
|
return node instanceof AST_AsyncArrow || node instanceof AST_Arrow;
|
||||||
}
|
}
|
||||||
|
|
||||||
var AST_AsyncFunction = DEFNODE("AsyncFunction", "inlined", {
|
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",
|
$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");
|
||||||
@@ -560,8 +657,11 @@ var AST_AsyncFunction = DEFNODE("AsyncFunction", "inlined", {
|
|||||||
},
|
},
|
||||||
}, AST_Lambda);
|
}, AST_Lambda);
|
||||||
|
|
||||||
var AST_Function = DEFNODE("Function", "inlined", {
|
var AST_Function = DEFNODE("Function", "inlined name", {
|
||||||
$documentation: "A function expression",
|
$documentation: "A 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");
|
||||||
@@ -573,15 +673,21 @@ function is_defun(node) {
|
|||||||
return node instanceof AST_AsyncDefun || node instanceof AST_Defun;
|
return node instanceof AST_AsyncDefun || node instanceof AST_Defun;
|
||||||
}
|
}
|
||||||
|
|
||||||
var AST_AsyncDefun = DEFNODE("AsyncDefun", "inlined", {
|
var AST_AsyncDefun = DEFNODE("AsyncDefun", "inlined name", {
|
||||||
$documentation: "An asynchronous function definition",
|
$documentation: "An asynchronous 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");
|
||||||
},
|
},
|
||||||
}, AST_Lambda);
|
}, AST_Lambda);
|
||||||
|
|
||||||
var AST_Defun = DEFNODE("Defun", "inlined", {
|
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");
|
||||||
},
|
},
|
||||||
@@ -747,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;
|
||||||
@@ -757,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);
|
||||||
|
|
||||||
@@ -795,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);
|
||||||
@@ -808,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);
|
||||||
@@ -821,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);
|
||||||
@@ -829,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;
|
||||||
@@ -839,18 +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 ]----- */
|
||||||
|
|
||||||
|
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) {
|
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 (!allow_hole && node instanceof AST_Hole) throw new Error(prop + " cannot be AST_Hole");
|
|
||||||
if (!allow_spread && node instanceof AST_Spread) throw new Error(prop + " cannot be AST_Spread");
|
|
||||||
if (node instanceof AST_Statement && !is_function(node)) {
|
|
||||||
throw new Error(prop + " cannot contain AST_Statement");
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1005,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");
|
||||||
},
|
},
|
||||||
@@ -1084,24 +1203,31 @@ var AST_Array = DEFNODE("Array", "elements", {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
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;
|
||||||
@@ -1109,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);
|
||||||
@@ -1117,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;
|
||||||
@@ -1131,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");
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1146,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() {
|
||||||
@@ -1275,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);
|
||||||
|
|
||||||
|
|||||||
1764
lib/compress.js
1764
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) {
|
||||||
|
|||||||
@@ -678,7 +678,7 @@ function OutputStream(options) {
|
|||||||
// 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);
|
||||||
|
|
||||||
@@ -691,6 +691,8 @@ function OutputStream(options) {
|
|||||||
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
|
||||||
|
// () => (foo, bar)
|
||||||
|
|| is_arrow(p) && p.value === this
|
||||||
// await (foo, bar)
|
// await (foo, bar)
|
||||||
|| p instanceof AST_Await
|
|| p instanceof AST_Await
|
||||||
// 1 + (2, 3) + 4 ==> 8
|
// 1 + (2, 3) + 4 ==> 8
|
||||||
@@ -700,6 +702,8 @@ function OutputStream(options) {
|
|||||||
// (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
|
||||||
|
// [ a = (1, 2) ] = [] ==> a == 2
|
||||||
|
|| p instanceof AST_DefaultValue
|
||||||
// { [(1, 2)]: 3 }[2] ==> 3
|
// { [(1, 2)]: 3 }[2] ==> 3
|
||||||
// { foo: (1, 2) }.foo ==> 2
|
// { foo: (1, 2) }.foo ==> 2
|
||||||
|| p instanceof AST_DestructuredKeyVal
|
|| p instanceof AST_DestructuredKeyVal
|
||||||
@@ -798,6 +802,9 @@ 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
|
||||||
@@ -806,6 +813,9 @@ function OutputStream(options) {
|
|||||||
// ({ 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);
|
||||||
});
|
});
|
||||||
@@ -985,17 +995,48 @@ function OutputStream(options) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
/* -----[ functions ]----- */
|
/* -----[ functions ]----- */
|
||||||
function print_lambda(self, output) {
|
function print_funargs(self, output) {
|
||||||
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);
|
||||||
}
|
}
|
||||||
@@ -1174,11 +1215,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);
|
||||||
}
|
}
|
||||||
@@ -1196,6 +1235,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) {
|
||||||
@@ -1322,25 +1370,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(",");
|
||||||
@@ -1349,6 +1402,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);
|
||||||
|
|||||||
427
lib/parse.js
427
lib/parse.js
@@ -569,6 +569,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;
|
||||||
@@ -634,7 +635,7 @@ var PRECEDENCE = function(a, ret) {
|
|||||||
["*", "/", "%"]
|
["*", "/", "%"]
|
||||||
], {});
|
], {});
|
||||||
|
|
||||||
var ATOMIC_START_TOKEN = makePredicate("atom num string regexp name");
|
var ATOMIC_START_TOKEN = makePredicate("atom num regexp string");
|
||||||
|
|
||||||
/* -----[ Parser ]----- */
|
/* -----[ Parser ]----- */
|
||||||
|
|
||||||
@@ -736,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;
|
||||||
}
|
}
|
||||||
@@ -769,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);
|
||||||
@@ -795,13 +796,14 @@ function parse($TEXT, options) {
|
|||||||
next();
|
next();
|
||||||
return function_(AST_AsyncDefun);
|
return function_(AST_AsyncDefun);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
case "await":
|
case "await":
|
||||||
if (S.in_async) return simple_statement();
|
if (S.in_async) return simple_statement();
|
||||||
default:
|
break;
|
||||||
return is_token(peek(), "punc", ":")
|
|
||||||
? labeled_statement()
|
|
||||||
: simple_statement();
|
|
||||||
}
|
}
|
||||||
|
return is_token(peek(), "punc", ":")
|
||||||
|
? labeled_statement()
|
||||||
|
: simple_statement();
|
||||||
|
|
||||||
case "punc":
|
case "punc":
|
||||||
switch (S.token.value) {
|
switch (S.token.value) {
|
||||||
@@ -887,7 +889,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({
|
||||||
@@ -905,7 +907,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
|
||||||
@@ -956,9 +958,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);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -966,7 +966,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 });
|
||||||
}
|
}
|
||||||
@@ -980,7 +980,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();
|
||||||
@@ -999,13 +999,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);
|
||||||
@@ -1016,9 +1017,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,
|
||||||
@@ -1029,7 +1030,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,
|
||||||
@@ -1038,6 +1039,110 @@ 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 was_async = S.in_async;
|
var was_async = S.in_async;
|
||||||
var name;
|
var name;
|
||||||
@@ -1057,7 +1162,7 @@ function parse($TEXT, options) {
|
|||||||
var was_funarg = S.in_funarg;
|
var was_funarg = S.in_funarg;
|
||||||
S.in_funarg = S.in_function;
|
S.in_funarg = S.in_function;
|
||||||
var argnames = expr_list(")", !options.strict, false, function() {
|
var argnames = expr_list(")", !options.strict, false, function() {
|
||||||
return maybe_destructured(AST_SymbolFunarg);
|
return maybe_default(AST_SymbolFunarg);
|
||||||
});
|
});
|
||||||
S.in_funarg = was_funarg;
|
S.in_funarg = was_funarg;
|
||||||
var loop = S.in_loop;
|
var loop = S.in_loop;
|
||||||
@@ -1071,6 +1176,7 @@ 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;
|
||||||
@@ -1080,6 +1186,7 @@ function parse($TEXT, options) {
|
|||||||
return new ctor({
|
return new ctor({
|
||||||
name: name,
|
name: name,
|
||||||
argnames: argnames,
|
argnames: argnames,
|
||||||
|
rest: argnames.rest || null,
|
||||||
body: body
|
body: body
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -1101,7 +1208,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();
|
||||||
@@ -1112,13 +1219,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);
|
||||||
@@ -1151,7 +1258,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({
|
||||||
@@ -1187,7 +1294,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");
|
||||||
}
|
}
|
||||||
@@ -1251,9 +1358,6 @@ 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;
|
||||||
@@ -1295,7 +1399,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;
|
||||||
@@ -1318,6 +1426,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);
|
||||||
@@ -1326,20 +1435,42 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
unexpected();
|
unexpected();
|
||||||
}
|
}
|
||||||
var ctor;
|
if (is("keyword", "function")) {
|
||||||
if (is("name", "async") && is_token(peek(), "keyword", "function")) {
|
|
||||||
next();
|
next();
|
||||||
ctor = AST_AsyncFunction;
|
var func = function_(AST_Function);
|
||||||
} else if (is("keyword", "function")) {
|
|
||||||
ctor = AST_Function;
|
|
||||||
}
|
|
||||||
if (ctor) {
|
|
||||||
next();
|
|
||||||
var func = function_(ctor);
|
|
||||||
func.start = start;
|
func.start = start;
|
||||||
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);
|
||||||
}
|
}
|
||||||
@@ -1347,24 +1478,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 (allow_empty && is("punc", ",")) {
|
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 if (parser === expression && is("operator", "...")) {
|
} else if (!is("operator", "...")) {
|
||||||
|
a.push(parser());
|
||||||
|
} else if (parser === maybe_assign) {
|
||||||
a.push(new AST_Spread({
|
a.push(new AST_Spread({
|
||||||
start: S.token,
|
start: S.token,
|
||||||
expression: (next(), parser()),
|
expression: (next(), parser()),
|
||||||
end: prev(),
|
end: prev(),
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
a.push(parser());
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1391,7 +1527,33 @@ function parse($TEXT, options) {
|
|||||||
next();
|
next();
|
||||||
a.push(new AST_Spread({
|
a.push(new AST_Spread({
|
||||||
start: start,
|
start: start,
|
||||||
expression: expression(false),
|
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(),
|
end: prev(),
|
||||||
}));
|
}));
|
||||||
continue;
|
continue;
|
||||||
@@ -1410,7 +1572,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,
|
||||||
@@ -1427,22 +1612,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 });
|
||||||
@@ -1461,9 +1632,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:
|
||||||
@@ -1472,9 +1642,8 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1490,7 +1659,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) {
|
||||||
@@ -1510,50 +1679,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;
|
||||||
@@ -1580,7 +1780,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,
|
||||||
@@ -1629,11 +1829,11 @@ 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 });
|
||||||
@@ -1679,13 +1879,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()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1698,22 +1898,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,
|
||||||
@@ -1724,11 +1949,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]) {
|
||||||
@@ -1745,23 +1971,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;
|
||||||
@@ -1772,7 +2003,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() {
|
||||||
|
|||||||
94
lib/scope.js
94
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,
|
||||||
@@ -118,6 +119,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
|||||||
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;
|
||||||
@@ -206,32 +208,46 @@ 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;
|
||||||
}
|
}
|
||||||
// ensure mangling works if `catch` reuses a scope variable
|
if (node instanceof AST_SymbolDeclaration) {
|
||||||
if (node instanceof AST_SymbolCatch) {
|
if (node instanceof AST_SymbolCatch) {
|
||||||
var def = node.definition().redefined();
|
// ensure mangling works if `catch` reuses a scope variable
|
||||||
if (def) for (var s = node.scope; s; s = s.parent_scope) {
|
var def = node.definition().redefined();
|
||||||
push_uniq(s.enclosed, def);
|
if (def) for (var s = node.scope; s; s = s.parent_scope) {
|
||||||
if (s === def.scope) break;
|
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;
|
||||||
}
|
}
|
||||||
return true;
|
if (node.name != "arguments") return true;
|
||||||
}
|
var parent = node instanceof AST_SymbolVar && tw.parent();
|
||||||
// ensure compression works if `const` reuses a scope variable
|
if (parent instanceof AST_VarDef && !parent.value) return true;
|
||||||
if (node instanceof AST_SymbolConst) {
|
var sym = node.scope.resolve().find_variable("arguments");
|
||||||
var redef = node.definition().redefined();
|
if (sym && is_arguments(sym)) sym.scope.uses_arguments = 3;
|
||||||
if (redef) redef.const_redefs = true;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (node instanceof AST_SymbolRef) {
|
if (node instanceof AST_SymbolRef) {
|
||||||
@@ -241,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;
|
||||||
}
|
}
|
||||||
@@ -249,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;
|
||||||
}
|
}
|
||||||
@@ -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;
|
||||||
@@ -485,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 = [];
|
||||||
@@ -516,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) {
|
||||||
@@ -575,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);
|
||||||
}
|
}
|
||||||
@@ -589,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);
|
||||||
@@ -168,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);
|
||||||
@@ -175,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.2",
|
"version": "3.12.5",
|
||||||
"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");
|
||||||
|
|||||||
@@ -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"
|
||||||
|
}
|
||||||
|
|||||||
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"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,498 +0,0 @@
|
|||||||
await_await: {
|
|
||||||
input: {
|
|
||||||
(async function() {
|
|
||||||
console.log("PASS");
|
|
||||||
await await 42;
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
(async function() {
|
|
||||||
console.log("PASS");
|
|
||||||
await await 42;
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
node_version: ">=8"
|
|
||||||
}
|
|
||||||
|
|
||||||
defun_name: {
|
|
||||||
input: {
|
|
||||||
async function await() {
|
|
||||||
console.log("PASS");
|
|
||||||
}
|
|
||||||
await();
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
async function await() {
|
|
||||||
console.log("PASS");
|
|
||||||
}
|
|
||||||
await();
|
|
||||||
}
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
node_version: ">=8"
|
|
||||||
}
|
|
||||||
|
|
||||||
nested_await: {
|
|
||||||
input: {
|
|
||||||
(async function() {
|
|
||||||
console.log(function(await) {
|
|
||||||
return await;
|
|
||||||
}("PASS"));
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
(async function() {
|
|
||||||
console.log(function(await) {
|
|
||||||
return await;
|
|
||||||
}("PASS"));
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
node_version: ">=8"
|
|
||||||
}
|
|
||||||
|
|
||||||
reduce_single_use_defun: {
|
|
||||||
options = {
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
async function f(a) {
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
f("PASS");
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
(async function(a) {
|
|
||||||
console.log(a);
|
|
||||||
})("PASS");
|
|
||||||
}
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
node_version: ">=8"
|
|
||||||
}
|
|
||||||
|
|
||||||
dont_inline: {
|
|
||||||
options = {
|
|
||||||
inline: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
(async function() {
|
|
||||||
A;
|
|
||||||
})().catch(function() {});
|
|
||||||
console.log("PASS");
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
(async function() {
|
|
||||||
A;
|
|
||||||
})().catch(function() {});
|
|
||||||
console.log("PASS");
|
|
||||||
}
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
node_version: ">=8"
|
|
||||||
}
|
|
||||||
|
|
||||||
evaluate: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var a = async function() {}();
|
|
||||||
console.log(typeof a);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var a = async function() {}();
|
|
||||||
console.log(typeof a);
|
|
||||||
}
|
|
||||||
expect_stdout: "object"
|
|
||||||
node_version: ">=8"
|
|
||||||
}
|
|
||||||
|
|
||||||
negate: {
|
|
||||||
options = {
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
console && async function() {} && console.log("PASS");
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console && async function() {} && console.log("PASS");
|
|
||||||
}
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
node_version: ">=8"
|
|
||||||
}
|
|
||||||
|
|
||||||
negate_iife: {
|
|
||||||
options = {
|
|
||||||
negate_iife: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
(async function() {
|
|
||||||
console.log("PASS");
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
!async function() {
|
|
||||||
console.log("PASS");
|
|
||||||
}();
|
|
||||||
}
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
node_version: ">=8"
|
|
||||||
}
|
|
||||||
|
|
||||||
collapse_vars_1: {
|
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var a = "FAIL";
|
|
||||||
(async function() {
|
|
||||||
a = "PASS";
|
|
||||||
await 42;
|
|
||||||
return "PASS";
|
|
||||||
})();
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var a = "FAIL";
|
|
||||||
(async function() {
|
|
||||||
a = "PASS";
|
|
||||||
await 42;
|
|
||||||
return "PASS";
|
|
||||||
})();
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
node_version: ">=8"
|
|
||||||
}
|
|
||||||
|
|
||||||
collapse_vars_2: {
|
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var a = "FAIL";
|
|
||||||
(async function() {
|
|
||||||
await (a = "PASS");
|
|
||||||
return "PASS";
|
|
||||||
})();
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var a = "FAIL";
|
|
||||||
(async function() {
|
|
||||||
await (a = "PASS");
|
|
||||||
return "PASS";
|
|
||||||
})();
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
node_version: ">=8"
|
|
||||||
}
|
|
||||||
|
|
||||||
collapse_vars_3: {
|
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var a = "FAIL";
|
|
||||||
(async function() {
|
|
||||||
await (a = "PASS", 42);
|
|
||||||
return "PASS";
|
|
||||||
})();
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var a = "FAIL";
|
|
||||||
(async function() {
|
|
||||||
await (a = "PASS", 42);
|
|
||||||
return "PASS";
|
|
||||||
})();
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
node_version: ">=8"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_4335_1: {
|
|
||||||
options = {
|
|
||||||
inline: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var await = "PASS";
|
|
||||||
(async function() {
|
|
||||||
console.log(function() {
|
|
||||||
return await;
|
|
||||||
}());
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var await = "PASS";
|
|
||||||
(async function() {
|
|
||||||
console.log(function() {
|
|
||||||
return await;
|
|
||||||
}());
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
node_version: ">=8"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_4335_2: {
|
|
||||||
options = {
|
|
||||||
inline: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
(async function() {
|
|
||||||
console.log(function() {
|
|
||||||
function await() {}
|
|
||||||
return "PASS";
|
|
||||||
}());
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
(async function() {
|
|
||||||
console.log(function() {
|
|
||||||
function await() {}
|
|
||||||
return "PASS";
|
|
||||||
}());
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
node_version: ">=8"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_4337: {
|
|
||||||
options = {
|
|
||||||
reduce_vars: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
(function(a) {
|
|
||||||
a();
|
|
||||||
})(async function() {
|
|
||||||
console.log("PASS");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
(function(a) {
|
|
||||||
(async function() {
|
|
||||||
console.log("PASS");
|
|
||||||
})();
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
node_version: ">=8"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_4340: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
(async function a(a) {
|
|
||||||
console.log(a || "PASS");
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
(async function a(a) {
|
|
||||||
console.log(a || "PASS");
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
node_version: ">=8"
|
|
||||||
}
|
|
||||||
|
|
||||||
call_expression: {
|
|
||||||
input: {
|
|
||||||
console.log(typeof async function(log) {
|
|
||||||
(await log)("FAIL");
|
|
||||||
}(console.log).then);
|
|
||||||
}
|
|
||||||
expect_exact: 'console.log(typeof async function(log){(await log)("FAIL")}(console.log).then);'
|
|
||||||
expect_stdout: "function"
|
|
||||||
node_version: ">=8"
|
|
||||||
}
|
|
||||||
|
|
||||||
property_access_expression: {
|
|
||||||
input: {
|
|
||||||
console.log(typeof async function(con) {
|
|
||||||
(await con).log("FAIL");
|
|
||||||
}(console).then);
|
|
||||||
}
|
|
||||||
expect_exact: 'console.log(typeof async function(con){(await con).log("FAIL")}(console).then);'
|
|
||||||
expect_stdout: "function"
|
|
||||||
node_version: ">=8"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_4347_1: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var a = "foo";
|
|
||||||
f();
|
|
||||||
a = "bar";
|
|
||||||
f();
|
|
||||||
async function f() {
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var a = "foo";
|
|
||||||
f();
|
|
||||||
a = "bar";
|
|
||||||
f();
|
|
||||||
async function f() {
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect_stdout: [
|
|
||||||
"foo",
|
|
||||||
"bar",
|
|
||||||
]
|
|
||||||
node_version: ">=8"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_4347_2: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var a = "PASS";
|
|
||||||
(async function() {
|
|
||||||
throw 42;
|
|
||||||
a = "FAIL";
|
|
||||||
})();
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var a = "PASS";
|
|
||||||
(async function() {
|
|
||||||
throw 42;
|
|
||||||
a = "FAIL";
|
|
||||||
})();
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
node_version: ">=8"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_4349_1: {
|
|
||||||
input: {
|
|
||||||
console.log(typeof async function() {
|
|
||||||
await /abc/;
|
|
||||||
}().then);
|
|
||||||
}
|
|
||||||
expect_exact: "console.log(typeof async function(){await/abc/}().then);"
|
|
||||||
expect_stdout: "function"
|
|
||||||
node_version: ">=8"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_4349_2: {
|
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
console.log(typeof async function() {
|
|
||||||
(function(a) {
|
|
||||||
this[a];
|
|
||||||
}(await 0));
|
|
||||||
}().then);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log(typeof async function() {
|
|
||||||
(function(a) {
|
|
||||||
this[a];
|
|
||||||
}(await 0));
|
|
||||||
}().then);
|
|
||||||
}
|
|
||||||
expect_stdout: "function"
|
|
||||||
node_version: ">=8"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_4349_3: {
|
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
console.log(typeof function(await) {
|
|
||||||
return async function(a) {
|
|
||||||
this[a];
|
|
||||||
}(await);
|
|
||||||
}(this).then);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log(typeof function(await) {
|
|
||||||
return async function(a) {
|
|
||||||
this[a];
|
|
||||||
}(await);
|
|
||||||
}(this).then);
|
|
||||||
}
|
|
||||||
expect_stdout: "function"
|
|
||||||
node_version: ">=8"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_4359: {
|
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
try {
|
|
||||||
(async function(a) {
|
|
||||||
return a;
|
|
||||||
})(A);
|
|
||||||
} catch (e) {
|
|
||||||
console.log("PASS");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
try {
|
|
||||||
(async function(a) {
|
|
||||||
return a;
|
|
||||||
})(A);
|
|
||||||
} catch (e) {
|
|
||||||
console.log("PASS");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
node_version: ">=8"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_4377: {
|
|
||||||
options = {
|
|
||||||
dead_code: true,
|
|
||||||
inline: true,
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
console.log(typeof function() {
|
|
||||||
return function() {
|
|
||||||
f;
|
|
||||||
async function f() {}
|
|
||||||
return f();
|
|
||||||
}();
|
|
||||||
}().then);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log(typeof function() {
|
|
||||||
return f();
|
|
||||||
async function f() {}
|
|
||||||
}().then);
|
|
||||||
}
|
|
||||||
expect_stdout: "function"
|
|
||||||
node_version: ">=8"
|
|
||||||
}
|
|
||||||
997
test/compress/awaits.js
Normal file
997
test/compress/awaits.js
Normal file
@@ -0,0 +1,997 @@
|
|||||||
|
async_arrow: {
|
||||||
|
input: {
|
||||||
|
(async a => console.log(a))("PASS");
|
||||||
|
console.log(typeof (async () => 42)());
|
||||||
|
}
|
||||||
|
expect_exact: '(async a=>console.log(a))("PASS");console.log(typeof(async()=>42)());'
|
||||||
|
expect_stdout: [
|
||||||
|
"PASS",
|
||||||
|
"object",
|
||||||
|
]
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
async_label: {
|
||||||
|
input: {
|
||||||
|
(async function() {
|
||||||
|
async: console.log("PASS");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_exact: '(async function(){async:console.log("PASS")})();'
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
await_await: {
|
||||||
|
input: {
|
||||||
|
(async function() {
|
||||||
|
console.log("PASS");
|
||||||
|
await await 42;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(async function() {
|
||||||
|
console.log("PASS");
|
||||||
|
await await 42;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_name: {
|
||||||
|
input: {
|
||||||
|
async function await() {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
await();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
async function await() {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
await();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_fname: {
|
||||||
|
rename = true
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
async function await() {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
await();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(async function() {
|
||||||
|
console.log("PASS");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
keep_fname: {
|
||||||
|
options = {
|
||||||
|
keep_fnames: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
async function await() {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
await();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
async function await() {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
await();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
nested_await: {
|
||||||
|
input: {
|
||||||
|
(async function() {
|
||||||
|
console.log(function(await) {
|
||||||
|
return await;
|
||||||
|
}("PASS"));
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(async function() {
|
||||||
|
console.log(function(await) {
|
||||||
|
return await;
|
||||||
|
}("PASS"));
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce_single_use_defun: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
async function f(a) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
f("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(async function(a) {
|
||||||
|
console.log(a);
|
||||||
|
})("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
dont_inline: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(async function() {
|
||||||
|
A;
|
||||||
|
})().catch(function() {});
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(async function() {
|
||||||
|
A;
|
||||||
|
})().catch(function() {});
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
inline_await_1: {
|
||||||
|
options = {
|
||||||
|
awaits: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(async function() {
|
||||||
|
async function f() {
|
||||||
|
await 42;
|
||||||
|
}
|
||||||
|
return await f();
|
||||||
|
})();
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(async function() {
|
||||||
|
return await void await 42;
|
||||||
|
})();
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
inline_await_1_trim: {
|
||||||
|
options = {
|
||||||
|
awaits: true,
|
||||||
|
if_return: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(async function() {
|
||||||
|
async function f() {
|
||||||
|
await 42;
|
||||||
|
}
|
||||||
|
return await f();
|
||||||
|
})();
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(async function() {
|
||||||
|
await 0;
|
||||||
|
})();
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
inline_await_2: {
|
||||||
|
options = {
|
||||||
|
awaits: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(async function() {
|
||||||
|
async function f(a) {
|
||||||
|
await a;
|
||||||
|
}
|
||||||
|
return await f(console);
|
||||||
|
})();
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(async function() {
|
||||||
|
return await void await console;
|
||||||
|
})();
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
inline_await_2_trim: {
|
||||||
|
options = {
|
||||||
|
awaits: true,
|
||||||
|
if_return: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(async function() {
|
||||||
|
async function f(a) {
|
||||||
|
await a.log;
|
||||||
|
}
|
||||||
|
return await f(console);
|
||||||
|
})();
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(async function() {
|
||||||
|
await console.log;
|
||||||
|
})();
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
inline_await_3: {
|
||||||
|
options = {
|
||||||
|
awaits: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(async function() {
|
||||||
|
async function f(a, b) {
|
||||||
|
return await b(a);
|
||||||
|
}
|
||||||
|
return await f("PASS", console.log);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(async function() {
|
||||||
|
return await (a = "PASS", b = console.log, await b(a));
|
||||||
|
var a, b;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
inline_await_3_trim: {
|
||||||
|
options = {
|
||||||
|
awaits: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(async function() {
|
||||||
|
async function f(a, b) {
|
||||||
|
return await b(a);
|
||||||
|
}
|
||||||
|
return await f("PASS", console.log);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(async function() {
|
||||||
|
return a = "PASS", b = console.log, await b(a);
|
||||||
|
var a, b;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
await_unary: {
|
||||||
|
options = {
|
||||||
|
awaits: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
(async function() {
|
||||||
|
a = "PASS";
|
||||||
|
await delete a.p;
|
||||||
|
a = "FAIL";
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
(async function() {
|
||||||
|
a = "PASS";
|
||||||
|
await delete a.p;
|
||||||
|
a = "FAIL";
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
await_void: {
|
||||||
|
options = {
|
||||||
|
awaits: true,
|
||||||
|
if_return: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(async function() {
|
||||||
|
console.log("PASS");
|
||||||
|
return await void 42;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(async function() {
|
||||||
|
await console.log("PASS");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
evaluate: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = async function() {}();
|
||||||
|
console.log(typeof a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = async function() {}();
|
||||||
|
console.log(typeof a);
|
||||||
|
}
|
||||||
|
expect_stdout: "object"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
negate: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console && async function() {} && console.log("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console && async function() {} && console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
negate_iife: {
|
||||||
|
options = {
|
||||||
|
negate_iife: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(async function() {
|
||||||
|
console.log("PASS");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!async function() {
|
||||||
|
console.log("PASS");
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
object_function: {
|
||||||
|
options = {
|
||||||
|
properties: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
({
|
||||||
|
async f() {
|
||||||
|
console.log("PASS");
|
||||||
|
},
|
||||||
|
}).f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(async function() {
|
||||||
|
console.log("PASS");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
collapse_vars_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "FAIL";
|
||||||
|
(async function() {
|
||||||
|
a = "PASS";
|
||||||
|
await 42;
|
||||||
|
return "PASS";
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "FAIL";
|
||||||
|
(async function() {
|
||||||
|
a = "PASS";
|
||||||
|
await 42;
|
||||||
|
return "PASS";
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
collapse_vars_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "FAIL";
|
||||||
|
(async function() {
|
||||||
|
await (a = "PASS");
|
||||||
|
return "PASS";
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "FAIL";
|
||||||
|
(async function() {
|
||||||
|
await (a = "PASS");
|
||||||
|
return "PASS";
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
collapse_vars_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "FAIL";
|
||||||
|
(async function() {
|
||||||
|
await (a = "PASS", 42);
|
||||||
|
return "PASS";
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "FAIL";
|
||||||
|
(async function() {
|
||||||
|
await (a = "PASS", 42);
|
||||||
|
return "PASS";
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4335_1: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var await = "PASS";
|
||||||
|
(async function() {
|
||||||
|
console.log(function() {
|
||||||
|
return await;
|
||||||
|
}());
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var await = "PASS";
|
||||||
|
(async function() {
|
||||||
|
console.log(function() {
|
||||||
|
return await;
|
||||||
|
}());
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4335_2: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(async function() {
|
||||||
|
console.log(function() {
|
||||||
|
function await() {}
|
||||||
|
return "PASS";
|
||||||
|
}());
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(async function() {
|
||||||
|
console.log(function() {
|
||||||
|
function await() {}
|
||||||
|
return "PASS";
|
||||||
|
}());
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4337: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a) {
|
||||||
|
a();
|
||||||
|
})(async function() {
|
||||||
|
console.log("PASS");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a) {
|
||||||
|
(async function() {
|
||||||
|
console.log("PASS");
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4340: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(async function a(a) {
|
||||||
|
console.log(a || "PASS");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(async function a(a) {
|
||||||
|
console.log(a || "PASS");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
call_expression: {
|
||||||
|
input: {
|
||||||
|
console.log(typeof async function(log) {
|
||||||
|
(await log)("FAIL");
|
||||||
|
}(console.log).then);
|
||||||
|
}
|
||||||
|
expect_exact: 'console.log(typeof async function(log){(await log)("FAIL")}(console.log).then);'
|
||||||
|
expect_stdout: "function"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
property_access_expression: {
|
||||||
|
input: {
|
||||||
|
console.log(typeof async function(con) {
|
||||||
|
(await con).log("FAIL");
|
||||||
|
}(console).then);
|
||||||
|
}
|
||||||
|
expect_exact: 'console.log(typeof async function(con){(await con).log("FAIL")}(console).then);'
|
||||||
|
expect_stdout: "function"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce_iife_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(async function(a) {
|
||||||
|
console.log(a + a);
|
||||||
|
})(21);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(async function() {
|
||||||
|
console.log(42);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce_iife_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 21;
|
||||||
|
(async function() {
|
||||||
|
console.log(a + a);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(async function() {
|
||||||
|
console.log(42);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce_iife_3: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "foo";
|
||||||
|
(async function() {
|
||||||
|
console.log(a);
|
||||||
|
console.log(await a);
|
||||||
|
})();
|
||||||
|
a = "bar";
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "foo";
|
||||||
|
(async function() {
|
||||||
|
console.log(a);
|
||||||
|
console.log(await a);
|
||||||
|
})();
|
||||||
|
a = "bar";
|
||||||
|
}
|
||||||
|
expect_stdout: "foo"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4347_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "foo";
|
||||||
|
f();
|
||||||
|
a = "bar";
|
||||||
|
f();
|
||||||
|
async function f() {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "foo";
|
||||||
|
f();
|
||||||
|
a = "bar";
|
||||||
|
f();
|
||||||
|
async function f() {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"foo",
|
||||||
|
"bar",
|
||||||
|
]
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4347_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS";
|
||||||
|
(async function() {
|
||||||
|
throw 42;
|
||||||
|
a = "FAIL";
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "PASS";
|
||||||
|
(async function() {
|
||||||
|
throw 42;
|
||||||
|
a = "FAIL";
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4349_1: {
|
||||||
|
input: {
|
||||||
|
console.log(typeof async function() {
|
||||||
|
await /abc/;
|
||||||
|
}().then);
|
||||||
|
}
|
||||||
|
expect_exact: "console.log(typeof async function(){await/abc/}().then);"
|
||||||
|
expect_stdout: "function"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4349_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(typeof async function() {
|
||||||
|
(function(a) {
|
||||||
|
this[a];
|
||||||
|
}(await 0));
|
||||||
|
}().then);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(typeof async function() {
|
||||||
|
(function(a) {
|
||||||
|
this[a];
|
||||||
|
}(await 0));
|
||||||
|
}().then);
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4349_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(typeof function(await) {
|
||||||
|
return async function(a) {
|
||||||
|
this[a];
|
||||||
|
}(await);
|
||||||
|
}(this).then);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(typeof function(await) {
|
||||||
|
return async function(a) {
|
||||||
|
this[a];
|
||||||
|
}(await);
|
||||||
|
}(this).then);
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4359: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
(async function(a) {
|
||||||
|
return a;
|
||||||
|
})(A);
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
(async function(a) {
|
||||||
|
return a;
|
||||||
|
})(A);
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4377: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
inline: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(typeof function() {
|
||||||
|
return function() {
|
||||||
|
f;
|
||||||
|
async function f() {}
|
||||||
|
return f();
|
||||||
|
}();
|
||||||
|
}().then);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(typeof function() {
|
||||||
|
return f();
|
||||||
|
async function f() {}
|
||||||
|
}().then);
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4406: {
|
||||||
|
options = {
|
||||||
|
merge_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
A = "PASS";
|
||||||
|
B = "FAIL";
|
||||||
|
(function() {
|
||||||
|
var a, b;
|
||||||
|
a = A;
|
||||||
|
(async function({
|
||||||
|
[console.log(a)]: {},
|
||||||
|
}) {})((b = B) && { undefined: b });
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
A = "PASS";
|
||||||
|
B = "FAIL";
|
||||||
|
(function() {
|
||||||
|
var a, b;
|
||||||
|
a = A;
|
||||||
|
(async function({
|
||||||
|
[console.log(a)]: {},
|
||||||
|
}) {})((b = B) && { undefined: b });
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4417: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(async function() {
|
||||||
|
console.log(function() {
|
||||||
|
return await => 0;
|
||||||
|
}().prototype);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(async function() {
|
||||||
|
console.log(function() {
|
||||||
|
return await => 0;
|
||||||
|
}().prototype);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4454_1: {
|
||||||
|
rename = false
|
||||||
|
options = {
|
||||||
|
merge_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
(async function(b = console.log(a)) {})();
|
||||||
|
var await = 42..toString();
|
||||||
|
console.log(await);
|
||||||
|
}
|
||||||
|
f("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
(async function(b = console.log(a)) {})();
|
||||||
|
var await = 42..toString();
|
||||||
|
console.log(await);
|
||||||
|
}
|
||||||
|
f("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"PASS",
|
||||||
|
"42",
|
||||||
|
]
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4454_2: {
|
||||||
|
rename = true
|
||||||
|
options = {
|
||||||
|
merge_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
(async function(b = console.log(a)) {})();
|
||||||
|
var await = 42..toString();
|
||||||
|
console.log(await);
|
||||||
|
}
|
||||||
|
f("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(b) {
|
||||||
|
(async function(c = console.log(b)) {})();
|
||||||
|
var b = 42..toString();
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
f("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"PASS",
|
||||||
|
"42",
|
||||||
|
]
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4534: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(await) {
|
||||||
|
(async () => console.log(arguments[0]))();
|
||||||
|
})("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(await) {
|
||||||
|
(async () => console.log(arguments[0]))();
|
||||||
|
})("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
@@ -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");
|
||||||
}
|
}
|
||||||
@@ -5996,7 +5995,7 @@ issue_3215_1: {
|
|||||||
}());
|
}());
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log(typeof 42);
|
console.log("number");
|
||||||
}
|
}
|
||||||
expect_stdout: "number"
|
expect_stdout: "number"
|
||||||
}
|
}
|
||||||
@@ -8602,3 +8601,107 @@ 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"
|
||||||
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
@@ -1375,3 +1399,38 @@ issue_4365_2: {
|
|||||||
}
|
}
|
||||||
expect_stdout: true
|
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);
|
||||||
}
|
}
|
||||||
@@ -1399,3 +1399,21 @@ issue_4366: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
node_version: ">=4"
|
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"
|
||||||
|
}
|
||||||
|
|||||||
1598
test/compress/default-values.js
Normal file
1598
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;
|
||||||
@@ -1844,3 +1928,562 @@ issue_4372_2: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
node_version: ">=6"
|
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"
|
||||||
|
}
|
||||||
|
|||||||
@@ -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: {
|
||||||
@@ -2435,7 +2407,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 +2669,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 +2684,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 +2702,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 +2716,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 +2735,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 +2798,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 +2921,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 +3085,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"
|
||||||
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
@@ -5223,3 +5225,61 @@ trailing_comma: {
|
|||||||
expect_exact: '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"
|
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"
|
||||||
|
}
|
||||||
|
|||||||
@@ -2900,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"
|
||||||
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
}
|
}
|
||||||
@@ -1455,7 +1368,7 @@ issue_3619: {
|
|||||||
|
|
||||||
issue_4353_1: {
|
issue_4353_1: {
|
||||||
options = {
|
options = {
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
@@ -1470,7 +1383,7 @@ issue_4353_1: {
|
|||||||
|
|
||||||
issue_4353_2: {
|
issue_4353_2: {
|
||||||
options = {
|
options = {
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
@@ -1280,3 +1280,33 @@ issue_4355: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
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,
|
||||||
|
|||||||
@@ -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"
|
||||||
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
@@ -413,3 +436,22 @@ issue_4380: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
node_version: ">=4"
|
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,
|
||||||
|
|||||||
@@ -1208,3 +1208,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"
|
||||||
|
}
|
||||||
|
|||||||
665
test/compress/rests.js
Normal file
665
test/compress/rests.js
Normal file
@@ -0,0 +1,665 @@
|
|||||||
|
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"
|
||||||
|
}
|
||||||
@@ -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,
|
||||||
|
|||||||
@@ -85,6 +85,28 @@ collapse_vars_4: {
|
|||||||
node_version: ">=6"
|
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: {
|
dont_inline: {
|
||||||
options = {
|
options = {
|
||||||
inline: true,
|
inline: true,
|
||||||
@@ -106,7 +128,7 @@ dont_inline: {
|
|||||||
do_inline: {
|
do_inline: {
|
||||||
options = {
|
options = {
|
||||||
inline: true,
|
inline: true,
|
||||||
spread: true,
|
spreads: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
console.log(function(a) {
|
console.log(function(a) {
|
||||||
@@ -145,7 +167,7 @@ drop_empty_call_1: {
|
|||||||
drop_empty_call_2: {
|
drop_empty_call_2: {
|
||||||
options = {
|
options = {
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
spread: true,
|
spreads: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
(function() {})(...[ console.log("PASS") ]);
|
(function() {})(...[ console.log("PASS") ]);
|
||||||
@@ -159,7 +181,7 @@ drop_empty_call_2: {
|
|||||||
|
|
||||||
convert_hole: {
|
convert_hole: {
|
||||||
options = {
|
options = {
|
||||||
spread: true,
|
spreads: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
console.log(...[ "PASS", , 42 ]);
|
console.log(...[ "PASS", , 42 ]);
|
||||||
@@ -192,7 +214,7 @@ keep_property_access: {
|
|||||||
|
|
||||||
keep_fargs: {
|
keep_fargs: {
|
||||||
options = {
|
options = {
|
||||||
keep_fargs: "strict",
|
keep_fargs: false,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -253,7 +275,7 @@ reduce_vars_2: {
|
|||||||
convert_setter: {
|
convert_setter: {
|
||||||
options = {
|
options = {
|
||||||
objects: true,
|
objects: true,
|
||||||
spread: true,
|
spreads: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var o = {
|
var o = {
|
||||||
@@ -397,7 +419,7 @@ keep_getter_4: {
|
|||||||
keep_accessor: {
|
keep_accessor: {
|
||||||
options = {
|
options = {
|
||||||
objects: true,
|
objects: true,
|
||||||
spread: true,
|
spreads: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var o = {
|
var o = {
|
||||||
@@ -445,7 +467,7 @@ keep_accessor: {
|
|||||||
object_key_order_1: {
|
object_key_order_1: {
|
||||||
options = {
|
options = {
|
||||||
objects: true,
|
objects: true,
|
||||||
spread: true,
|
spreads: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var o = {
|
var o = {
|
||||||
@@ -475,7 +497,7 @@ object_key_order_1: {
|
|||||||
object_key_order_2: {
|
object_key_order_2: {
|
||||||
options = {
|
options = {
|
||||||
objects: true,
|
objects: true,
|
||||||
spread: true,
|
spreads: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var o = {
|
var o = {
|
||||||
@@ -505,7 +527,7 @@ object_key_order_2: {
|
|||||||
object_key_order_3: {
|
object_key_order_3: {
|
||||||
options = {
|
options = {
|
||||||
objects: true,
|
objects: true,
|
||||||
spread: true,
|
spreads: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var o = {
|
var o = {
|
||||||
@@ -535,7 +557,7 @@ object_key_order_3: {
|
|||||||
object_key_order_4: {
|
object_key_order_4: {
|
||||||
options = {
|
options = {
|
||||||
objects: true,
|
objects: true,
|
||||||
spread: true,
|
spreads: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var o = {
|
var o = {
|
||||||
@@ -565,7 +587,7 @@ object_key_order_4: {
|
|||||||
object_spread_array: {
|
object_spread_array: {
|
||||||
options = {
|
options = {
|
||||||
objects: true,
|
objects: true,
|
||||||
spread: true,
|
spreads: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var o = {
|
var o = {
|
||||||
@@ -591,7 +613,7 @@ object_spread_array: {
|
|||||||
object_spread_string: {
|
object_spread_string: {
|
||||||
options = {
|
options = {
|
||||||
objects: true,
|
objects: true,
|
||||||
spread: true,
|
spreads: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var o = {
|
var o = {
|
||||||
@@ -648,7 +670,7 @@ unused_var_side_effects: {
|
|||||||
issue_4329: {
|
issue_4329: {
|
||||||
options = {
|
options = {
|
||||||
objects: true,
|
objects: true,
|
||||||
spread: true,
|
spreads: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
console.log({
|
console.log({
|
||||||
@@ -727,7 +749,7 @@ issue_4342: {
|
|||||||
issue_4345: {
|
issue_4345: {
|
||||||
options = {
|
options = {
|
||||||
objects: true,
|
objects: true,
|
||||||
spread: true,
|
spreads: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
console.log({
|
console.log({
|
||||||
@@ -787,7 +809,7 @@ issue_4361: {
|
|||||||
issue_4363: {
|
issue_4363: {
|
||||||
options = {
|
options = {
|
||||||
objects: true,
|
objects: true,
|
||||||
spread: true,
|
spreads: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
({
|
({
|
||||||
@@ -804,3 +826,95 @@ issue_4363: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
node_version: ">=8"
|
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) {
|
||||||
|
|||||||
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("...---...");
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -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() {
|
||||||
|
|||||||
@@ -104,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.
|
||||||
@@ -124,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 "++":
|
||||||
@@ -153,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);
|
||||||
}
|
}
|
||||||
@@ -175,6 +188,12 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
return expr instanceof U.AST_Spread ? expr.expression : 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
|
||||||
var body = node.expression.body;
|
var body = node.expression.body;
|
||||||
@@ -205,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:
|
||||||
@@ -298,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;
|
||||||
@@ -308,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;
|
||||||
@@ -410,15 +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
|
CHANGED = true;
|
||||||
|| parent instanceof U.AST_Destructured
|
return null;
|
||||||
|| parent instanceof U.AST_Object) {
|
|
||||||
node.start._permute++;
|
|
||||||
CHANGED = true;
|
|
||||||
return List.skip;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// replace this node
|
// replace this node
|
||||||
@@ -459,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)),
|
||||||
@@ -621,7 +666,7 @@ function has_loopcontrol(body, loop, label) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function is_error(result) {
|
function is_error(result) {
|
||||||
return typeof result == "object" && typeof result.name == "string" && typeof result.message == "string";
|
return result && typeof result.name == "string" && typeof result.message == "string";
|
||||||
}
|
}
|
||||||
|
|
||||||
function is_timed_out(result) {
|
function is_timed_out(result) {
|
||||||
@@ -629,7 +674,11 @@ function is_timed_out(result) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function is_statement(node) {
|
function is_statement(node) {
|
||||||
return node instanceof U.AST_Statement && !(node instanceof U.AST_AsyncFunction || 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) {
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ function createContext() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.run_code = function(code, toplevel, timeout) {
|
function run_code(code, toplevel, timeout) {
|
||||||
timeout = timeout || 5000;
|
timeout = timeout || 5000;
|
||||||
var stdout = "";
|
var stdout = "";
|
||||||
var original_write = process.stdout.write;
|
var original_write = process.stdout.write;
|
||||||
@@ -79,7 +79,17 @@ exports.run_code = function(code, toplevel, timeout) {
|
|||||||
} finally {
|
} finally {
|
||||||
process.stdout.write = original_write;
|
process.stdout.write = original_write;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
exports.run_code = semver.satisfies(process.version, "0.8") ? function(code, toplevel, timeout) {
|
||||||
|
var stdout = run_code(code, toplevel, timeout);
|
||||||
|
if (typeof stdout != "string" || !/arguments/.test(code)) return stdout;
|
||||||
|
do {
|
||||||
|
var prev = stdout;
|
||||||
|
stdout = run_code(code, toplevel, timeout);
|
||||||
|
} while (prev !== stdout);
|
||||||
|
return stdout;
|
||||||
|
} : run_code;
|
||||||
|
|
||||||
function strip_func_ids(text) {
|
function strip_func_ids(text) {
|
||||||
return ("" + text).replace(/F[0-9]{6}N/g, "<F<>N>");
|
return ("" + text).replace(/F[0-9]{6}N/g, "<F<>N>");
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
// bin/uglifyjs s.js -c && bin/uglifyjs s.js -c passes=3 && bin/uglifyjs s.js -c passes=3 -m
|
// bin/uglifyjs s.js -c && bin/uglifyjs s.js -c passes=3 && bin/uglifyjs s.js -c passes=3 -m
|
||||||
// cat s.js | node && node s.js && bin/uglifyjs s.js -c | node && bin/uglifyjs s.js -c passes=3 | node && bin/uglifyjs s.js -c passes=3 -m | node
|
// cat s.js | node && node s.js && bin/uglifyjs s.js -c | node && bin/uglifyjs s.js -c passes=3 | node && bin/uglifyjs s.js -c passes=3 -m | node
|
||||||
|
|
||||||
require("../../tools/exit");
|
require("../../tools/tty");
|
||||||
|
|
||||||
var UglifyJS = require("../..");
|
var UglifyJS = require("../..");
|
||||||
var randomBytes = require("crypto").randomBytes;
|
var randomBytes = require("crypto").randomBytes;
|
||||||
@@ -132,11 +132,16 @@ var SUPPORT = function(matrix) {
|
|||||||
}
|
}
|
||||||
return matrix;
|
return matrix;
|
||||||
}({
|
}({
|
||||||
|
arrow: "a => 0;",
|
||||||
async: "async function f(){}",
|
async: "async function f(){}",
|
||||||
catch_omit_var: "try {} catch {}",
|
catch_omit_var: "try {} catch {}",
|
||||||
computed_key: "({[0]: 0});",
|
computed_key: "({[0]: 0});",
|
||||||
|
const_block: "var a; { const a = 0; }",
|
||||||
|
default_value: "[ a = 0 ] = [];",
|
||||||
destructuring: "[] = [];",
|
destructuring: "[] = [];",
|
||||||
let: "let a;",
|
let: "let a;",
|
||||||
|
rest: "var [...a] = [];",
|
||||||
|
rest_object: "var {...a} = {};",
|
||||||
spread: "[...[]];",
|
spread: "[...[]];",
|
||||||
spread_object: "({...0});",
|
spread_object: "({...0});",
|
||||||
trailing_comma: "function f(a,) {}",
|
trailing_comma: "function f(a,) {}",
|
||||||
@@ -361,7 +366,7 @@ function createTopLevelCode() {
|
|||||||
return [
|
return [
|
||||||
strictMode(),
|
strictMode(),
|
||||||
"var _calls_ = 10, a = 100, b = 10, c = 0;",
|
"var _calls_ = 10, a = 100, b = 10, c = 0;",
|
||||||
rng(2) == 0
|
rng(2)
|
||||||
? createStatements(3, MAX_GENERATION_RECURSION_DEPTH, CANNOT_THROW, CANNOT_BREAK, CANNOT_CONTINUE, CANNOT_RETURN, 0)
|
? createStatements(3, MAX_GENERATION_RECURSION_DEPTH, CANNOT_THROW, CANNOT_BREAK, CANNOT_CONTINUE, CANNOT_RETURN, 0)
|
||||||
: createFunctions(rng(MAX_GENERATED_TOPLEVELS_PER_RUN) + 1, MAX_GENERATION_RECURSION_DEPTH, DEFUN_OK, CANNOT_THROW, 0),
|
: createFunctions(rng(MAX_GENERATED_TOPLEVELS_PER_RUN) + 1, MAX_GENERATION_RECURSION_DEPTH, DEFUN_OK, CANNOT_THROW, 0),
|
||||||
// preceding `null` makes for a cleaner output (empty string still shows up etc)
|
// preceding `null` makes for a cleaner output (empty string still shows up etc)
|
||||||
@@ -382,7 +387,9 @@ function addTrailingComma(list) {
|
|||||||
return SUPPORT.trailing_comma && list && rng(20) == 0 ? list + "," : list;
|
return SUPPORT.trailing_comma && list && rng(20) == 0 ? list + "," : list;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createParams(noDuplicate) {
|
function createParams(was_async, noDuplicate) {
|
||||||
|
var save_async = async;
|
||||||
|
if (was_async) async = true;
|
||||||
var len = unique_vars.length;
|
var len = unique_vars.length;
|
||||||
var params = [];
|
var params = [];
|
||||||
for (var n = rng(4); --n >= 0;) {
|
for (var n = rng(4); --n >= 0;) {
|
||||||
@@ -391,6 +398,7 @@ function createParams(noDuplicate) {
|
|||||||
params.push(name);
|
params.push(name);
|
||||||
}
|
}
|
||||||
unique_vars.length = len;
|
unique_vars.length = len;
|
||||||
|
async = save_async;
|
||||||
return addTrailingComma(params.join(", "));
|
return addTrailingComma(params.join(", "));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -411,59 +419,95 @@ function createArgs(recurmax, stmtDepth, canThrow) {
|
|||||||
args.push("..." + createArrayLiteral(recurmax, stmtDepth, canThrow));
|
args.push("..." + createArrayLiteral(recurmax, stmtDepth, canThrow));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
args.push(rng(2) ? createValue() : createExpression(recurmax, COMMA_OK, stmtDepth, canThrow));
|
args.push(rng(2) ? createValue() : createExpression(recurmax, NO_COMMA, stmtDepth, canThrow));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return addTrailingComma(args.join(", "));
|
return addTrailingComma(args.join(", "));
|
||||||
}
|
}
|
||||||
|
|
||||||
function createAssignmentPairs(recurmax, noComma, stmtDepth, canThrow, varNames, was_async) {
|
function createAssignmentPairs(recurmax, stmtDepth, canThrow, nameLenBefore, was_async) {
|
||||||
var avoid = [];
|
var avoid = [];
|
||||||
var len = unique_vars.length;
|
var len = unique_vars.length;
|
||||||
var pairs = createPairs(recurmax);
|
var pairs = createPairs(recurmax, !nameLenBefore);
|
||||||
|
pairs.has_rest = nameLenBefore && convertToRest(pairs.names);
|
||||||
unique_vars.length = len;
|
unique_vars.length = len;
|
||||||
return pairs;
|
return pairs;
|
||||||
|
|
||||||
function createAssignmentValue(recurmax) {
|
function convertToRest(names) {
|
||||||
var current = VAR_NAMES;
|
var last = names.length - 1;
|
||||||
VAR_NAMES = (varNames || VAR_NAMES).slice();
|
if (last >= 0 && SUPPORT.rest && rng(20) == 0) {
|
||||||
|
var name = names[last];
|
||||||
|
if (name && name.indexOf("=") < 0) {
|
||||||
|
if (/^[[{]/.test(name)) name = "[ " + name + " ]";
|
||||||
|
names[last] = "..." + name;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function fill(nameFn, valueFn) {
|
||||||
var save_async = async;
|
var save_async = async;
|
||||||
if (was_async != null) async = was_async;
|
if (was_async != null) {
|
||||||
var value = varNames && rng(2) ? createValue() : createExpression(recurmax, noComma, stmtDepth, canThrow);
|
async = false;
|
||||||
|
if (save_async || was_async) addAvoidVar("await");
|
||||||
|
}
|
||||||
|
avoid.forEach(addAvoidVar);
|
||||||
|
var save_vars = nameLenBefore && VAR_NAMES.splice(nameLenBefore);
|
||||||
|
if (nameFn) nameFn();
|
||||||
|
if (was_async != null) {
|
||||||
|
async = was_async;
|
||||||
|
if (save_async || was_async) removeAvoidVar("await");
|
||||||
|
}
|
||||||
|
if (valueFn) valueFn();
|
||||||
|
if (save_vars) [].push.apply(VAR_NAMES, save_vars);
|
||||||
|
avoid.forEach(removeAvoidVar);
|
||||||
async = save_async;
|
async = save_async;
|
||||||
VAR_NAMES = current;
|
}
|
||||||
return value;
|
|
||||||
|
function createAssignmentValue(recurmax) {
|
||||||
|
return nameLenBefore && rng(2) ? createValue() : createExpression(recurmax, NO_COMMA, stmtDepth, canThrow);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createDefaultValue(recurmax, noDefault) {
|
||||||
|
return !noDefault && SUPPORT.default_value && rng(20) == 0 ? " = " + createAssignmentValue(recurmax) : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
function createKey(recurmax, keys) {
|
function createKey(recurmax, keys) {
|
||||||
addAvoidVars(avoid);
|
|
||||||
var key;
|
var key;
|
||||||
do {
|
do {
|
||||||
key = createObjectKey(recurmax, stmtDepth, canThrow);
|
key = createObjectKey(recurmax, stmtDepth, canThrow);
|
||||||
} while (keys.indexOf(key) >= 0);
|
} while (keys.indexOf(key) >= 0);
|
||||||
removeAvoidVars(avoid);
|
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createPairs(recurmax) {
|
function createName() {
|
||||||
|
unique_vars.push("a", "b", "c", "undefined", "NaN", "Infinity");
|
||||||
|
var save_async = async;
|
||||||
|
if (was_async) async = true;
|
||||||
|
var name = createVarName(MANDATORY);
|
||||||
|
async = save_async;
|
||||||
|
unique_vars.length -= 6;
|
||||||
|
avoid.push(name);
|
||||||
|
unique_vars.push(name);
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createPairs(recurmax, noDefault) {
|
||||||
var names = [], values = [];
|
var names = [], values = [];
|
||||||
var m = rng(4), n = rng(4);
|
var m = rng(4), n = rng(4);
|
||||||
if (!varNames) m = Math.max(m, n, 1);
|
if (!nameLenBefore) m = Math.max(m, n, 1);
|
||||||
for (var i = Math.max(m, n); --i >= 0;) {
|
for (var i = Math.max(m, n); --i >= 0;) {
|
||||||
if (i < m && i < n) {
|
if (i < m && i < n) {
|
||||||
createDestructured(recurmax, names, values);
|
createDestructured(recurmax, noDefault, names, values);
|
||||||
continue;
|
} else if (i < m) {
|
||||||
}
|
var name = createName();
|
||||||
if (i < m) {
|
fill(function() {
|
||||||
unique_vars.push("a", "b", "c", "undefined", "NaN", "Infinity");
|
names.unshift(name + createDefaultValue(recurmax, noDefault));
|
||||||
var name = createVarName(MANDATORY);
|
});
|
||||||
unique_vars.length -= 6;
|
} else {
|
||||||
avoid.push(name);
|
fill(null, function() {
|
||||||
unique_vars.push(name);
|
values.unshift(createAssignmentValue(recurmax));
|
||||||
names.unshift(name);
|
});
|
||||||
}
|
|
||||||
if (i < n) {
|
|
||||||
values.unshift(createAssignmentValue(recurmax));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
@@ -472,7 +516,7 @@ function createAssignmentPairs(recurmax, noComma, stmtDepth, canThrow, varNames,
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function createDestructured(recurmax, names, values) {
|
function createDestructured(recurmax, noDefault, names, values) {
|
||||||
switch (rng(20)) {
|
switch (rng(20)) {
|
||||||
case 0:
|
case 0:
|
||||||
if (--recurmax < 0) {
|
if (--recurmax < 0) {
|
||||||
@@ -480,20 +524,26 @@ function createAssignmentPairs(recurmax, noComma, stmtDepth, canThrow, varNames,
|
|||||||
values.unshift('""');
|
values.unshift('""');
|
||||||
} else {
|
} else {
|
||||||
var pairs = createPairs(recurmax);
|
var pairs = createPairs(recurmax);
|
||||||
while (!rng(10)) {
|
var default_value;
|
||||||
var index = rng(pairs.names.length + 1);
|
fill(function() {
|
||||||
pairs.names.splice(index, 0, "");
|
default_value = createDefaultValue(recurmax, noDefault);
|
||||||
if (index < pairs.values.length) {
|
}, function() {
|
||||||
pairs.values.splice(index, 0, rng(2) ? createAssignmentValue(recurmax) : "");
|
while (!rng(10)) {
|
||||||
} else switch (rng(5)) {
|
var index = rng(pairs.names.length + 1);
|
||||||
case 0:
|
pairs.names.splice(index, 0, "");
|
||||||
pairs.values[index] = createAssignmentValue(recurmax);
|
if (index < pairs.values.length) {
|
||||||
case 1:
|
pairs.values.splice(index, 0, rng(2) ? createAssignmentValue(recurmax) : "");
|
||||||
pairs.values.length = index + 1;
|
} else switch (rng(5)) {
|
||||||
|
case 0:
|
||||||
|
pairs.values[index] = createAssignmentValue(recurmax);
|
||||||
|
case 1:
|
||||||
|
pairs.values.length = index + 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
convertToRest(pairs.names);
|
||||||
names.unshift("[ " + pairs.names.join(", ") + " ]");
|
names.unshift("[ " + pairs.names.join(", ") + " ]" + default_value);
|
||||||
values.unshift("[ " + pairs.values.join(", ") + " ]");
|
values.unshift("[ " + pairs.values.join(", ") + " ]");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
@@ -512,27 +562,33 @@ function createAssignmentPairs(recurmax, noComma, stmtDepth, canThrow, varNames,
|
|||||||
keys[index] = key;
|
keys[index] = key;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
names.unshift("{ " + addTrailingComma(pairs.names.map(function(name, index) {
|
fill(function() {
|
||||||
var key = index in keys ? keys[index] : rng(10) && createKey(recurmax, keys);
|
var last = pairs.names.length - 1, has_rest = false;
|
||||||
return key ? key + ": " + name : name;
|
var s = pairs.names.map(function(name, index) {
|
||||||
}).join(", ")) + " }");
|
if (index in keys) return keys[index] + ": " + name;
|
||||||
var save_async = async;
|
if (index == last && SUPPORT.rest_object && rng(20) == 0 && name.indexOf("=") < 0) {
|
||||||
if (was_async != null) async = was_async;
|
has_rest = true;
|
||||||
values.unshift("{ " + addTrailingComma(pairs.values.map(function(value, index) {
|
return "..." + name;
|
||||||
var key = index in keys ? keys[index] : createKey(recurmax, keys);
|
}
|
||||||
return key + ": " + value;
|
return rng(10) == 0 ? name : createKey(recurmax, keys) + ": " + name;
|
||||||
}).join(", ")) + " }");
|
}).join(", ");
|
||||||
async = save_async;
|
if (!has_rest) s = addTrailingComma(s);
|
||||||
|
names.unshift("{ " + s + " }" + createDefaultValue(recurmax, noDefault));
|
||||||
|
}, function() {
|
||||||
|
values.unshift("{ " + addTrailingComma(pairs.values.map(function(value, index) {
|
||||||
|
var key = index in keys ? keys[index] : createKey(recurmax, keys);
|
||||||
|
return key + ": " + value;
|
||||||
|
}).join(", ")) + " }");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
unique_vars.push("a", "b", "c", "undefined", "NaN", "Infinity");
|
var name = createName();
|
||||||
var name = createVarName(MANDATORY);
|
fill(function() {
|
||||||
unique_vars.length -= 6;
|
names.unshift(name + createDefaultValue(recurmax, noDefault));
|
||||||
avoid.push(name);
|
}, function() {
|
||||||
unique_vars.push(name);
|
values.unshift(createAssignmentValue(recurmax));
|
||||||
names.unshift(name);
|
});
|
||||||
values.unshift(createAssignmentValue(recurmax));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -545,12 +601,12 @@ function filterDirective(s) {
|
|||||||
|
|
||||||
function createBlockVariables(recurmax, stmtDepth, canThrow, fn) {
|
function createBlockVariables(recurmax, stmtDepth, canThrow, fn) {
|
||||||
var block_len = block_vars.length;
|
var block_len = block_vars.length;
|
||||||
var var_len = VAR_NAMES.length;
|
var nameLenBefore = VAR_NAMES.length;
|
||||||
var consts = [];
|
var consts = [];
|
||||||
var lets = [];
|
var lets = [];
|
||||||
unique_vars.push("a", "b", "c", "undefined", "NaN", "Infinity");
|
unique_vars.push("a", "b", "c", "undefined", "NaN", "Infinity");
|
||||||
while (!rng(block_vars.length > block_len ? 10 : 100)) {
|
while (!rng(block_vars.length > block_len ? 10 : 100)) {
|
||||||
var name = createVarName(MANDATORY, DONT_STORE);
|
var name = createVarName(MANDATORY);
|
||||||
if (SUPPORT.let && rng(2)) {
|
if (SUPPORT.let && rng(2)) {
|
||||||
lets.push(name);
|
lets.push(name);
|
||||||
} else {
|
} else {
|
||||||
@@ -560,16 +616,16 @@ function createBlockVariables(recurmax, stmtDepth, canThrow, fn) {
|
|||||||
}
|
}
|
||||||
unique_vars.length -= 6;
|
unique_vars.length -= 6;
|
||||||
fn(function() {
|
fn(function() {
|
||||||
addAvoidVars(consts);
|
consts.forEach(addAvoidVar);
|
||||||
addAvoidVars(lets);
|
lets.forEach(addAvoidVar);
|
||||||
if (rng(2)) {
|
if (rng(2)) {
|
||||||
return createDefinitions("const", consts) + "\n" + createDefinitions("let", lets) + "\n";
|
return createDefinitions("const", consts) + "\n" + createDefinitions("let", lets) + "\n";
|
||||||
} else {
|
} else {
|
||||||
return createDefinitions("let", lets) + "\n" + createDefinitions("const", consts) + "\n";
|
return createDefinitions("let", lets) + "\n" + createDefinitions("const", consts) + "\n";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
VAR_NAMES.length = nameLenBefore;
|
||||||
block_vars.length = block_len;
|
block_vars.length = block_len;
|
||||||
if (consts.length || lets.length) VAR_NAMES.splice(var_len, consts.length + lets.length);
|
|
||||||
|
|
||||||
function createDefinitions(type, names) {
|
function createDefinitions(type, names) {
|
||||||
if (!names.length) return "";
|
if (!names.length) return "";
|
||||||
@@ -595,20 +651,31 @@ function createBlockVariables(recurmax, stmtDepth, canThrow, fn) {
|
|||||||
default:
|
default:
|
||||||
s += names.map(function(name) {
|
s += names.map(function(name) {
|
||||||
if (type == "let" && !rng(10)) {
|
if (type == "let" && !rng(10)) {
|
||||||
removeAvoidVars([ name ]);
|
removeAvoidVar(name);
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
var value = createExpression(recurmax, NO_COMMA, stmtDepth, canThrow);
|
var value = createExpression(recurmax, NO_COMMA, stmtDepth, canThrow);
|
||||||
removeAvoidVars([ name ]);
|
removeAvoidVar(name);
|
||||||
return name + " = " + value;
|
return name + " = " + value;
|
||||||
}).join(", ") + ";";
|
}).join(", ") + ";";
|
||||||
|
names.length = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
removeAvoidVars(names);
|
names.forEach(removeAvoidVar);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mayCreateBlockVariables(recurmax, stmtDepth, canThrow, fn) {
|
||||||
|
if (SUPPORT.const_block) {
|
||||||
|
createBlockVariables(recurmax, stmtDepth, canThrow, fn);
|
||||||
|
} else {
|
||||||
|
fn(function() {
|
||||||
|
return "";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function makeFunction(name) {
|
function makeFunction(name) {
|
||||||
return (async ? "async function " : "function ") + name;
|
return (async ? "async function " : "function ") + name;
|
||||||
}
|
}
|
||||||
@@ -618,7 +685,7 @@ function createFunction(recurmax, allowDefun, canThrow, stmtDepth) {
|
|||||||
if (!STMT_COUNT_FROM_GLOBAL) stmtDepth = 0;
|
if (!STMT_COUNT_FROM_GLOBAL) stmtDepth = 0;
|
||||||
var s = [];
|
var s = [];
|
||||||
var name, args;
|
var name, args;
|
||||||
var varNames = VAR_NAMES.slice();
|
var nameLenBefore = VAR_NAMES.length;
|
||||||
var save_async = async;
|
var save_async = async;
|
||||||
async = SUPPORT.async && rng(50) == 0;
|
async = SUPPORT.async && rng(50) == 0;
|
||||||
createBlockVariables(recurmax, stmtDepth, canThrow, function(defns) {
|
createBlockVariables(recurmax, stmtDepth, canThrow, function(defns) {
|
||||||
@@ -632,11 +699,12 @@ function createFunction(recurmax, allowDefun, canThrow, stmtDepth) {
|
|||||||
var params;
|
var params;
|
||||||
if (SUPPORT.destructuring && (!allowDefun || !(name in called)) && rng(2)) {
|
if (SUPPORT.destructuring && (!allowDefun || !(name in called)) && rng(2)) {
|
||||||
called[name] = false;
|
called[name] = false;
|
||||||
var pairs = createAssignmentPairs(recurmax, COMMA_OK, stmtDepth, canThrow, varNames, save_async);
|
var pairs = createAssignmentPairs(recurmax, stmtDepth, canThrow, nameLenBefore, save_async);
|
||||||
params = addTrailingComma(pairs.names.join(", "));
|
params = pairs.names.join(", ");
|
||||||
|
if (!pairs.has_rest) params = addTrailingComma(params);
|
||||||
args = addTrailingComma(pairs.values.join(", "));
|
args = addTrailingComma(pairs.values.join(", "));
|
||||||
} else {
|
} else {
|
||||||
params = createParams();
|
params = createParams(save_async);
|
||||||
}
|
}
|
||||||
s.push(makeFunction(name) + "(" + params + "){", strictMode());
|
s.push(makeFunction(name) + "(" + params + "){", strictMode());
|
||||||
s.push(defns());
|
s.push(defns());
|
||||||
@@ -651,7 +719,7 @@ function createFunction(recurmax, allowDefun, canThrow, stmtDepth) {
|
|||||||
s = filterDirective(s).join("\n");
|
s = filterDirective(s).join("\n");
|
||||||
});
|
});
|
||||||
async = save_async;
|
async = save_async;
|
||||||
VAR_NAMES = varNames;
|
VAR_NAMES.length = nameLenBefore;
|
||||||
|
|
||||||
if (!allowDefun) {
|
if (!allowDefun) {
|
||||||
// avoid "function statements" (decl inside statements)
|
// avoid "function statements" (decl inside statements)
|
||||||
@@ -676,7 +744,7 @@ function _createStatements(n, recurmax, canThrow, canBreak, canContinue, cannotR
|
|||||||
|
|
||||||
function createStatements(n, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) {
|
function createStatements(n, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) {
|
||||||
var s = "";
|
var s = "";
|
||||||
createBlockVariables(recurmax, stmtDepth, canThrow, function(defns) {
|
mayCreateBlockVariables(recurmax, stmtDepth, canThrow, function(defns) {
|
||||||
s += defns() + "\n";
|
s += defns() + "\n";
|
||||||
s += _createStatements(n, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth);
|
s += _createStatements(n, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth);
|
||||||
});
|
});
|
||||||
@@ -736,7 +804,7 @@ function createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn
|
|||||||
var label = createLabel(canBreak);
|
var label = createLabel(canBreak);
|
||||||
return label.target + "{" + createStatements(rng(5) + 1, recurmax, canThrow, label.break, canContinue, cannotReturn, stmtDepth) + "}";
|
return label.target + "{" + createStatements(rng(5) + 1, recurmax, canThrow, label.break, canContinue, cannotReturn, stmtDepth) + "}";
|
||||||
case STMT_IF_ELSE:
|
case STMT_IF_ELSE:
|
||||||
return "if (" + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + ")" + createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) + (rng(2) === 1 ? " else " + createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) : "");
|
return "if (" + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + ")" + createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) + (rng(2) ? " else " + createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) : "");
|
||||||
case STMT_DO_WHILE:
|
case STMT_DO_WHILE:
|
||||||
var label = createLabel(canBreak, canContinue);
|
var label = createLabel(canBreak, canContinue);
|
||||||
canBreak = label.break || enableLoopControl(canBreak, CAN_BREAK);
|
canBreak = label.break || enableLoopControl(canBreak, CAN_BREAK);
|
||||||
@@ -777,7 +845,7 @@ function createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn
|
|||||||
return "switch (" + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + ") { " + createSwitchParts(recurmax, 4, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) + "}";
|
return "switch (" + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + ") { " + createSwitchParts(recurmax, 4, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) + "}";
|
||||||
case STMT_VAR:
|
case STMT_VAR:
|
||||||
if (SUPPORT.destructuring && rng(20) == 0) {
|
if (SUPPORT.destructuring && rng(20) == 0) {
|
||||||
var pairs = createAssignmentPairs(recurmax, NO_COMMA, stmtDepth, canThrow);
|
var pairs = createAssignmentPairs(recurmax, stmtDepth, canThrow);
|
||||||
return "var " + pairs.names.map(function(name, index) {
|
return "var " + pairs.names.map(function(name, index) {
|
||||||
return index in pairs.values ? name + " = " + pairs.values[index] : name;
|
return index in pairs.values ? name + " = " + pairs.values[index] : name;
|
||||||
}).join(", ") + ";";
|
}).join(", ") + ";";
|
||||||
@@ -836,22 +904,41 @@ function createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn
|
|||||||
if (n !== 1) {
|
if (n !== 1) {
|
||||||
// the catch var should only be accessible in the catch clause...
|
// the catch var should only be accessible in the catch clause...
|
||||||
// we have to do go through some trouble here to prevent leaking it
|
// we have to do go through some trouble here to prevent leaking it
|
||||||
var nameLenBefore = VAR_NAMES.length;
|
mayCreateBlockVariables(recurmax, stmtDepth, canThrow, function(defns) {
|
||||||
createBlockVariables(recurmax, stmtDepth, canThrow, function(defns) {
|
var block_len = block_vars.length;
|
||||||
if (SUPPORT.catch_omit_var && rng(20) == 0) {
|
var nameLenBefore = VAR_NAMES.length;
|
||||||
|
var unique_len = unique_vars.length;
|
||||||
|
if (SUPPORT.catch_omit_var && !rng(20)) {
|
||||||
s += " catch { ";
|
s += " catch { ";
|
||||||
|
} else if (canThrow && SUPPORT.destructuring && !rng(20)) {
|
||||||
|
unique_vars.push("a", "b", "c", "undefined", "NaN", "Infinity");
|
||||||
|
var name = createVarName(MANDATORY);
|
||||||
|
block_vars.push(name);
|
||||||
|
var message = createVarName(MANDATORY);
|
||||||
|
block_vars.push(message);
|
||||||
|
unique_vars.length -= 6;
|
||||||
|
if (SUPPORT.computed_key && rng(10) == 0) {
|
||||||
|
s += " catch ({ message: " + message + ", ";
|
||||||
|
addAvoidVar(name);
|
||||||
|
s += "[" + createExpression(recurmax, NO_COMMA, stmtDepth, canThrow) + "]: " + name;
|
||||||
|
removeAvoidVar(name);
|
||||||
|
s += " }) { ";
|
||||||
|
} else {
|
||||||
|
s += " catch ({ name: " + name + ", message: " + message + " }) { ";
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
var catchName = createVarName(MANDATORY);
|
var name = createVarName(MANDATORY);
|
||||||
if (!catch_redef) unique_vars.push(catchName);
|
if (!catch_redef) unique_vars.push(name);
|
||||||
s += " catch (" + catchName + ") { ";
|
s += " catch (" + name + ") { ";
|
||||||
}
|
}
|
||||||
var freshCatchName = VAR_NAMES.length !== nameLenBefore;
|
var catches = VAR_NAMES.length - nameLenBefore;
|
||||||
s += defns() + "\n";
|
s += defns() + "\n";
|
||||||
s += _createStatements(3, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth);
|
s += _createStatements(3, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth);
|
||||||
s += " }";
|
s += " }";
|
||||||
// remove catch name
|
// remove catch variables
|
||||||
if (!catch_redef) unique_vars.pop();
|
block_vars.length = block_len;
|
||||||
if (freshCatchName) VAR_NAMES.splice(nameLenBefore, 1);
|
if (catches > 0) VAR_NAMES.splice(nameLenBefore, catches);
|
||||||
|
unique_vars.length = unique_len;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (n !== 0) s += " finally { " + createStatements(3, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) + " }";
|
if (n !== 0) s += " finally { " + createStatements(3, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) + " }";
|
||||||
@@ -911,10 +998,10 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
|
|||||||
switch (rng(_createExpression.N)) {
|
switch (rng(_createExpression.N)) {
|
||||||
case p++:
|
case p++:
|
||||||
case p++:
|
case p++:
|
||||||
return createUnaryPrefix() + (rng(2) === 1 ? "a" : "b");
|
return createUnaryPrefix() + (rng(2) ? "a" : "b");
|
||||||
case p++:
|
case p++:
|
||||||
case p++:
|
case p++:
|
||||||
return (rng(2) === 1 ? "a" : "b") + createUnaryPostfix();
|
return (rng(2) ? "a" : "b") + createUnaryPostfix();
|
||||||
case p++:
|
case p++:
|
||||||
case p++:
|
case p++:
|
||||||
// parens needed because assignments aren't valid unless they're the left-most op(s) in an expression
|
// parens needed because assignments aren't valid unless they're the left-most op(s) in an expression
|
||||||
@@ -966,12 +1053,58 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
|
|||||||
var s = [];
|
var s = [];
|
||||||
switch (rng(5)) {
|
switch (rng(5)) {
|
||||||
case 0:
|
case 0:
|
||||||
s.push(
|
if (SUPPORT.arrow && !name && rng(2)) {
|
||||||
"(" + makeFunction(name) + "(){",
|
var args, suffix;
|
||||||
strictMode(),
|
(rng(2) ? createBlockVariables : function() {
|
||||||
createStatements(rng(5) + 1, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth),
|
arguments[3]();
|
||||||
rng(2) == 0 ? "})" : "})()"
|
})(recurmax, stmtDepth, canThrow, function(defns) {
|
||||||
);
|
var params;
|
||||||
|
if (SUPPORT.destructuring && rng(2)) {
|
||||||
|
var pairs = createAssignmentPairs(recurmax, stmtDepth, canThrow, nameLenBefore, save_async);
|
||||||
|
params = pairs.names.join(", ");
|
||||||
|
if (!pairs.has_rest) params = addTrailingComma(params);
|
||||||
|
args = addTrailingComma(pairs.values.join(", "));
|
||||||
|
} else {
|
||||||
|
params = createParams(save_async, NO_DUPLICATE);
|
||||||
|
}
|
||||||
|
params = (async ? "async (" : "(") + params + ") => ";
|
||||||
|
if (defns) {
|
||||||
|
s.push(
|
||||||
|
"(" + params + "{",
|
||||||
|
strictMode(),
|
||||||
|
defns(),
|
||||||
|
_createStatements(rng(5) + 1, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth)
|
||||||
|
);
|
||||||
|
suffix = "})";
|
||||||
|
} else {
|
||||||
|
s.push("(" + params);
|
||||||
|
switch (rng(10)) {
|
||||||
|
case 0:
|
||||||
|
s.push('(typeof arguments != "undefined" && arguments && arguments[' + rng(3) + "])");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
s.push("(this && this." + getDotKey() + ")");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
s.push(createExpression(recurmax, NO_COMMA, stmtDepth, canThrow));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
suffix = ")";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
async = save_async;
|
||||||
|
VAR_NAMES.length = nameLenBefore;
|
||||||
|
if (!args && rng(2)) args = createArgs(recurmax, stmtDepth, canThrow);
|
||||||
|
if (args) suffix += "(" + args + ")";
|
||||||
|
s.push(suffix);
|
||||||
|
} else {
|
||||||
|
s.push(
|
||||||
|
"(" + makeFunction(name) + "(){",
|
||||||
|
strictMode(),
|
||||||
|
createStatements(rng(5) + 1, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth),
|
||||||
|
rng(2) ? "})" : "})()"
|
||||||
|
);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
s.push(
|
s.push(
|
||||||
@@ -1002,7 +1135,7 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
|
|||||||
createBlockVariables(recurmax, stmtDepth, canThrow, function(defns) {
|
createBlockVariables(recurmax, stmtDepth, canThrow, function(defns) {
|
||||||
var instantiate = rng(4) ? "new " : "";
|
var instantiate = rng(4) ? "new " : "";
|
||||||
s.push(
|
s.push(
|
||||||
instantiate + "function " + name + "(" + createParams() + "){",
|
instantiate + "function " + name + "(" + createParams(save_async) + "){",
|
||||||
strictMode(),
|
strictMode(),
|
||||||
defns()
|
defns()
|
||||||
);
|
);
|
||||||
@@ -1014,7 +1147,7 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
|
|||||||
});
|
});
|
||||||
async = save_async;
|
async = save_async;
|
||||||
VAR_NAMES.length = nameLenBefore;
|
VAR_NAMES.length = nameLenBefore;
|
||||||
s.push(rng(2) == 0 ? "}" : "}(" + createArgs(recurmax, stmtDepth, canThrow) + ")");
|
s.push(rng(2) ? "}" : "}(" + createArgs(recurmax, stmtDepth, canThrow) + ")");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
async = save_async;
|
async = save_async;
|
||||||
@@ -1175,13 +1308,16 @@ function createObjectKey(recurmax, stmtDepth, canThrow) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function createObjectFunction(recurmax, stmtDepth, canThrow) {
|
function createObjectFunction(recurmax, stmtDepth, canThrow) {
|
||||||
var namesLenBefore = VAR_NAMES.length;
|
var nameLenBefore = VAR_NAMES.length;
|
||||||
|
var save_async = async;
|
||||||
var s;
|
var s;
|
||||||
|
var name = createObjectKey(recurmax, stmtDepth, canThrow);
|
||||||
createBlockVariables(recurmax, stmtDepth, canThrow, function(defns) {
|
createBlockVariables(recurmax, stmtDepth, canThrow, function(defns) {
|
||||||
switch (rng(SUPPORT.computed_key ? 3 : 2)) {
|
switch (rng(SUPPORT.computed_key ? 3 : 2)) {
|
||||||
case 0:
|
case 0:
|
||||||
|
async = false;
|
||||||
s = [
|
s = [
|
||||||
"get " + createObjectKey(recurmax, stmtDepth, canThrow) + "(){",
|
"get " + name + "(){",
|
||||||
strictMode(),
|
strictMode(),
|
||||||
defns(),
|
defns(),
|
||||||
_createStatements(2, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth),
|
_createStatements(2, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth),
|
||||||
@@ -1190,23 +1326,24 @@ function createObjectFunction(recurmax, stmtDepth, canThrow) {
|
|||||||
];
|
];
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
var prop1 = createObjectKey(recurmax, stmtDepth, canThrow);
|
var prop;
|
||||||
var prop2;
|
|
||||||
do {
|
do {
|
||||||
prop2 = getDotKey();
|
prop = getDotKey();
|
||||||
} while (prop1 == prop2);
|
} while (name == prop);
|
||||||
|
async = false;
|
||||||
s = [
|
s = [
|
||||||
"set " + prop1 + "(" + createVarName(MANDATORY) + "){",
|
"set " + name + "(" + createVarName(MANDATORY) + "){",
|
||||||
strictMode(),
|
strictMode(),
|
||||||
defns(),
|
defns(),
|
||||||
_createStatements(2, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth),
|
_createStatements(2, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth),
|
||||||
"this." + prop2 + createAssignment() + _createBinaryExpr(recurmax, COMMA_OK, stmtDepth, canThrow) + ";",
|
"this." + prop + createAssignment() + _createBinaryExpr(recurmax, COMMA_OK, stmtDepth, canThrow) + ";",
|
||||||
"},",
|
"},",
|
||||||
];
|
];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
async = SUPPORT.async && rng(50) == 0;
|
||||||
s = [
|
s = [
|
||||||
createObjectKey(recurmax, stmtDepth, canThrow) + "(" + createParams(NO_DUPLICATE) + "){",
|
(async ? "async " : "") + name + "(" + createParams(save_async, NO_DUPLICATE) + "){",
|
||||||
strictMode(),
|
strictMode(),
|
||||||
defns(),
|
defns(),
|
||||||
_createStatements(3, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth),
|
_createStatements(3, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth),
|
||||||
@@ -1215,7 +1352,8 @@ function createObjectFunction(recurmax, stmtDepth, canThrow) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
VAR_NAMES.length = namesLenBefore;
|
async = save_async;
|
||||||
|
VAR_NAMES.length = nameLenBefore;
|
||||||
return filterDirective(s).join("\n");
|
return filterDirective(s).join("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1347,18 +1485,26 @@ function _createSimpleBinaryExpr(recurmax, noComma, stmtDepth, canThrow) {
|
|||||||
function createTypeofExpr(recurmax, stmtDepth, canThrow) {
|
function createTypeofExpr(recurmax, stmtDepth, canThrow) {
|
||||||
switch (rng(8)) {
|
switch (rng(8)) {
|
||||||
case 0:
|
case 0:
|
||||||
return "(typeof " + createVarName(MANDATORY, DONT_STORE) + ' === "' + TYPEOF_OUTCOMES[rng(TYPEOF_OUTCOMES.length)] + '")';
|
return "(typeof " + createVar() + ' === "' + TYPEOF_OUTCOMES[rng(TYPEOF_OUTCOMES.length)] + '")';
|
||||||
case 1:
|
case 1:
|
||||||
return "(typeof " + createVarName(MANDATORY, DONT_STORE) + ' !== "' + TYPEOF_OUTCOMES[rng(TYPEOF_OUTCOMES.length)] + '")';
|
return "(typeof " + createVar() + ' !== "' + TYPEOF_OUTCOMES[rng(TYPEOF_OUTCOMES.length)] + '")';
|
||||||
case 2:
|
case 2:
|
||||||
return "(typeof " + createVarName(MANDATORY, DONT_STORE) + ' == "' + TYPEOF_OUTCOMES[rng(TYPEOF_OUTCOMES.length)] + '")';
|
return "(typeof " + createVar() + ' == "' + TYPEOF_OUTCOMES[rng(TYPEOF_OUTCOMES.length)] + '")';
|
||||||
case 3:
|
case 3:
|
||||||
return "(typeof " + createVarName(MANDATORY, DONT_STORE) + ' != "' + TYPEOF_OUTCOMES[rng(TYPEOF_OUTCOMES.length)] + '")';
|
return "(typeof " + createVar() + ' != "' + TYPEOF_OUTCOMES[rng(TYPEOF_OUTCOMES.length)] + '")';
|
||||||
case 4:
|
case 4:
|
||||||
return "(typeof " + createVarName(MANDATORY, DONT_STORE) + ")";
|
return "(typeof " + createVar() + ")";
|
||||||
default:
|
default:
|
||||||
return "(typeof " + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + ")";
|
return "(typeof " + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createVar() {
|
||||||
|
var save_async = async;
|
||||||
|
if (!async && avoid_vars.indexOf("await") >= 0) async = true;
|
||||||
|
var name = createVarName(MANDATORY, DONT_STORE);
|
||||||
|
async = save_async;
|
||||||
|
return name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function createValue() {
|
function createValue() {
|
||||||
@@ -1389,15 +1535,13 @@ function createUnaryPostfix() {
|
|||||||
return UNARY_POSTFIX[rng(UNARY_POSTFIX.length)];
|
return UNARY_POSTFIX[rng(UNARY_POSTFIX.length)];
|
||||||
}
|
}
|
||||||
|
|
||||||
function addAvoidVars(names) {
|
function addAvoidVar(name) {
|
||||||
avoid_vars = avoid_vars.concat(names);
|
avoid_vars.push(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeAvoidVars(names) {
|
function removeAvoidVar(name) {
|
||||||
names.forEach(function(name) {
|
var index = avoid_vars.lastIndexOf(name);
|
||||||
var index = avoid_vars.lastIndexOf(name);
|
if (index >= 0) avoid_vars.splice(index, 1);
|
||||||
if (index >= 0) avoid_vars.splice(index, 1);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getVarName(noConst) {
|
function getVarName(noConst) {
|
||||||
@@ -1406,7 +1550,7 @@ function getVarName(noConst) {
|
|||||||
do {
|
do {
|
||||||
if (--tries < 0) return "a";
|
if (--tries < 0) return "a";
|
||||||
name = VAR_NAMES[INITIAL_NAMES_LEN + rng(VAR_NAMES.length - INITIAL_NAMES_LEN)];
|
name = VAR_NAMES[INITIAL_NAMES_LEN + rng(VAR_NAMES.length - INITIAL_NAMES_LEN)];
|
||||||
} while (!name || avoid_vars.indexOf(name) >= 0 || noConst && block_vars.indexOf(name) >= 0);
|
} while (!name || avoid_vars.indexOf(name) >= 0 || noConst && block_vars.indexOf(name) >= 0 || async && name == "await");
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1418,7 +1562,7 @@ function createVarName(maybe, dontStore) {
|
|||||||
name = VAR_NAMES[rng(VAR_NAMES.length)];
|
name = VAR_NAMES[rng(VAR_NAMES.length)];
|
||||||
if (suffix) name += "_" + suffix;
|
if (suffix) name += "_" + suffix;
|
||||||
} while (unique_vars.indexOf(name) >= 0 || block_vars.indexOf(name) >= 0 || async && name == "await");
|
} while (unique_vars.indexOf(name) >= 0 || block_vars.indexOf(name) >= 0 || async && name == "await");
|
||||||
if (suffix && !dontStore) VAR_NAMES.push(name);
|
if (!dontStore) VAR_NAMES.push(name);
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
@@ -1570,18 +1714,20 @@ function log(options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
errorln("//-------------------------------------------------------------");
|
errorln("//-------------------------------------------------------------");
|
||||||
var reduce_options = JSON.parse(options);
|
if (!ok) {
|
||||||
reduce_options.validate = true;
|
var reduce_options = JSON.parse(options);
|
||||||
var reduced = reduce_test(original_code, reduce_options, {
|
reduce_options.validate = true;
|
||||||
verbose: false,
|
var reduced = reduce_test(original_code, reduce_options, {
|
||||||
}).code;
|
verbose: false,
|
||||||
if (reduced) {
|
}).code;
|
||||||
errorln();
|
if (reduced) {
|
||||||
errorln("// reduced test case (output will differ)");
|
errorln();
|
||||||
errorln();
|
errorln("// reduced test case (output will differ)");
|
||||||
errorln(reduced);
|
errorln();
|
||||||
errorln();
|
errorln(reduced);
|
||||||
errorln("//-------------------------------------------------------------");
|
errorln();
|
||||||
|
errorln("//-------------------------------------------------------------");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
errorln("minify(options):");
|
errorln("minify(options):");
|
||||||
errorln(JSON.stringify(JSON.parse(options), null, 2));
|
errorln(JSON.stringify(JSON.parse(options), null, 2));
|
||||||
@@ -1598,7 +1744,9 @@ function log(options) {
|
|||||||
|
|
||||||
function sort_globals(code) {
|
function sort_globals(code) {
|
||||||
var globals = sandbox.run_code("throw Object.keys(this).sort();" + code);
|
var globals = sandbox.run_code("throw Object.keys(this).sort();" + code);
|
||||||
return globals.length ? "var " + globals.join(",") + ";" + code : code;
|
return globals.length ? "var " + globals.map(function(name) {
|
||||||
|
return name + "=" + name;
|
||||||
|
}).join(",") + ";" + code : code;
|
||||||
}
|
}
|
||||||
|
|
||||||
function fuzzy_match(original, uglified) {
|
function fuzzy_match(original, uglified) {
|
||||||
@@ -1615,6 +1763,18 @@ function fuzzy_match(original, uglified) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function is_error_in(ex) {
|
||||||
|
return ex.name == "TypeError" && /'in'/.test(ex.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
function is_error_spread(ex) {
|
||||||
|
return ex.name == "TypeError" && /Found non-callable @@iterator|is not iterable|undefined is not a function/.test(ex.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
function is_error_recursion(ex) {
|
||||||
|
return ex.name == "RangeError" && /Invalid string length|Maximum call stack size exceeded/.test(ex.message);
|
||||||
|
}
|
||||||
|
|
||||||
function patch_try_catch(orig, toplevel) {
|
function patch_try_catch(orig, toplevel) {
|
||||||
var stack = [ {
|
var stack = [ {
|
||||||
code: orig,
|
code: orig,
|
||||||
@@ -1622,7 +1782,7 @@ function patch_try_catch(orig, toplevel) {
|
|||||||
offset: 0,
|
offset: 0,
|
||||||
tries: [],
|
tries: [],
|
||||||
} ];
|
} ];
|
||||||
var re = /(?:(?:^|[\s{}):;])try|}\s*catch\s*\(([^)]+)\)|}\s*finally)\s*(?={)/g;
|
var re = /(?:(?:^|[\s{}):;])try|}\s*catch\s*\(([^)[{]+)\)|}\s*finally)\s*(?={)/g;
|
||||||
while (stack.length) {
|
while (stack.length) {
|
||||||
var code = stack[0].code;
|
var code = stack[0].code;
|
||||||
var offset = stack[0].offset;
|
var offset = stack[0].offset;
|
||||||
@@ -1663,13 +1823,13 @@ function patch_try_catch(orig, toplevel) {
|
|||||||
});
|
});
|
||||||
offset += insert.length;
|
offset += insert.length;
|
||||||
code = new_code;
|
code = new_code;
|
||||||
} else if (result.name == "TypeError" && /'in'/.test(result.message)) {
|
} else if (is_error_in(result)) {
|
||||||
index = result.ufuzz_catch;
|
index = result.ufuzz_catch;
|
||||||
return orig.slice(0, index) + result.ufuzz_var + ' = new Error("invalid `in`");' + orig.slice(index);
|
return orig.slice(0, index) + result.ufuzz_var + ' = new Error("invalid `in`");' + orig.slice(index);
|
||||||
} else if (result.name == "TypeError" && /not iterable/.test(result.message)) {
|
} else if (is_error_spread(result)) {
|
||||||
index = result.ufuzz_catch;
|
index = result.ufuzz_catch;
|
||||||
return orig.slice(0, index) + result.ufuzz_var + ' = new Error("spread not iterable");' + orig.slice(index);
|
return orig.slice(0, index) + result.ufuzz_var + ' = new Error("spread not iterable");' + orig.slice(index);
|
||||||
} else if (result.name == "RangeError" && result.message == "Maximum call stack size exceeded") {
|
} else if (is_error_recursion(result)) {
|
||||||
index = result.ufuzz_try;
|
index = result.ufuzz_try;
|
||||||
return orig.slice(0, index) + 'throw new Error("skipping infinite recursion");' + orig.slice(index);
|
return orig.slice(0, index) + 'throw new Error("skipping infinite recursion");' + orig.slice(index);
|
||||||
}
|
}
|
||||||
@@ -1687,6 +1847,18 @@ var beautify_options = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
var minify_options = require("./options.json");
|
var minify_options = require("./options.json");
|
||||||
|
if (typeof sandbox.run_code("A:if (0) B:; else B:;") != "string") {
|
||||||
|
minify_options.forEach(function(o) {
|
||||||
|
if (!("mangle" in o)) o.mangle = {};
|
||||||
|
if (o.mangle) o.mangle.v8 = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
var is_bug_async_arrow_rest = function() {};
|
||||||
|
if (SUPPORT.arrow && SUPPORT.async && SUPPORT.rest && typeof sandbox.run_code("async (a = f(...[], b)) => 0;") != "string") {
|
||||||
|
is_bug_async_arrow_rest = function(ex) {
|
||||||
|
return ex.name == "SyntaxError" && ex.message == "Rest parameter must be last formal parameter";
|
||||||
|
};
|
||||||
|
}
|
||||||
if (SUPPORT.destructuring && typeof sandbox.run_code("console.log([ 1 ], {} = 2);") != "string") {
|
if (SUPPORT.destructuring && typeof sandbox.run_code("console.log([ 1 ], {} = 2);") != "string") {
|
||||||
beautify_options.output.v8 = true;
|
beautify_options.output.v8 = true;
|
||||||
minify_options.forEach(function(o) {
|
minify_options.forEach(function(o) {
|
||||||
@@ -1705,6 +1877,8 @@ for (var round = 1; round <= num_iterations; round++) {
|
|||||||
var orig_result = [ sandbox.run_code(original_code), sandbox.run_code(original_code, true) ];
|
var orig_result = [ sandbox.run_code(original_code), sandbox.run_code(original_code, true) ];
|
||||||
errored = typeof orig_result[0] != "string";
|
errored = typeof orig_result[0] != "string";
|
||||||
if (errored) {
|
if (errored) {
|
||||||
|
println();
|
||||||
|
println();
|
||||||
println("//=============================================================");
|
println("//=============================================================");
|
||||||
println("// original code");
|
println("// original code");
|
||||||
try_beautify(original_code, false, orig_result[0], println);
|
try_beautify(original_code, false, orig_result[0], println);
|
||||||
@@ -1713,6 +1887,7 @@ for (var round = 1; round <= num_iterations; round++) {
|
|||||||
println("original result:");
|
println("original result:");
|
||||||
println(orig_result[0]);
|
println(orig_result[0]);
|
||||||
println();
|
println();
|
||||||
|
if (is_bug_async_arrow_rest(orig_result[0])) continue;
|
||||||
}
|
}
|
||||||
minify_options.forEach(function(options) {
|
minify_options.forEach(function(options) {
|
||||||
var o = JSON.parse(options);
|
var o = JSON.parse(options);
|
||||||
@@ -1744,8 +1919,14 @@ for (var round = 1; round <= num_iterations; round++) {
|
|||||||
ok = sandbox.same_stdout(orig_result[toplevel ? 3 : 2], uglify_result);
|
ok = sandbox.same_stdout(orig_result[toplevel ? 3 : 2], uglify_result);
|
||||||
}
|
}
|
||||||
// ignore difference in error message caused by `in`
|
// ignore difference in error message caused by `in`
|
||||||
|
if (!ok && errored && is_error_in(uglify_result) && is_error_in(original_result)) ok = true;
|
||||||
// ignore difference in error message caused by spread syntax
|
// ignore difference in error message caused by spread syntax
|
||||||
|
if (!ok && errored && is_error_spread(uglify_result) && is_error_spread(original_result)) ok = true;
|
||||||
// ignore difference in depth of termination caused by infinite recursion
|
// ignore difference in depth of termination caused by infinite recursion
|
||||||
|
if (!ok && errored && is_error_recursion(original_result)) {
|
||||||
|
if (is_error_recursion(uglify_result) || typeof uglify_result == "string") ok = true;
|
||||||
|
}
|
||||||
|
// ignore errors above when caught by try-catch
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
var orig_skipped = patch_try_catch(original_code, toplevel);
|
var orig_skipped = patch_try_catch(original_code, toplevel);
|
||||||
var uglify_skipped = patch_try_catch(uglify_code, toplevel);
|
var uglify_skipped = patch_try_catch(uglify_code, toplevel);
|
||||||
|
|||||||
@@ -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