Compare commits
182 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
787dfbed64 | ||
|
|
6b23899ef3 | ||
|
|
8c5a899986 | ||
|
|
ed36c1ec5c | ||
|
|
ce8ef52e2b | ||
|
|
6669ea19ef | ||
|
|
205a1d1f19 | ||
|
|
95d3ede664 | ||
|
|
8195a664fd | ||
|
|
9c80456634 | ||
|
|
dc7aa32172 | ||
|
|
23d74bedeb | ||
|
|
f31311e439 | ||
|
|
87c9edbbc7 | ||
|
|
8dc99fa25f | ||
|
|
dc51a23d31 | ||
|
|
0934c0e431 | ||
|
|
ca4185a0fd | ||
|
|
e7b9b4aafb | ||
|
|
3dfb379486 | ||
|
|
2cb6454b1f | ||
|
|
09910771a1 | ||
|
|
c21a8eee7b | ||
|
|
34b6143306 | ||
|
|
ffe0fe7762 | ||
|
|
aa7c3389e6 | ||
|
|
30fd331bf1 | ||
|
|
f0ca9cfbe6 | ||
|
|
a437a61518 | ||
|
|
57dd3f6a2c | ||
|
|
f07dc5cfba | ||
|
|
358faaacaa | ||
|
|
c9117041fa | ||
|
|
f2b6f1def0 | ||
|
|
797184f587 | ||
|
|
78242ff21d | ||
|
|
dd88f3866b | ||
|
|
17c3ae6cba | ||
|
|
0cbd5ea64a | ||
|
|
404794f5db | ||
|
|
650e63c8aa | ||
|
|
59e385591c | ||
|
|
574ca47666 | ||
|
|
548f0938e8 | ||
|
|
2352909c3d | ||
|
|
4e7744af2d | ||
|
|
aef7065262 | ||
|
|
24c3db11e6 | ||
|
|
e5cbd3e0f3 | ||
|
|
68d62a8a31 | ||
|
|
21aff996a5 | ||
|
|
1d400f1a25 | ||
|
|
7f424a55c5 | ||
|
|
e37a1489d4 | ||
|
|
2b1c321ac8 | ||
|
|
8d28052182 | ||
|
|
f40dbd6e33 | ||
|
|
7270671687 | ||
|
|
30bf068768 | ||
|
|
fb1bff2c0a | ||
|
|
19c471c16a | ||
|
|
8319badea8 | ||
|
|
5a5200d657 | ||
|
|
5411360829 | ||
|
|
7edd10e5e5 | ||
|
|
bccb1c3bd9 | ||
|
|
ed7051b9bb | ||
|
|
a391897388 | ||
|
|
4a1da492dd | ||
|
|
94a954c3d1 | ||
|
|
be8ccc3ab5 | ||
|
|
58d997a3d6 | ||
|
|
dabcc39b51 | ||
|
|
140e4e0da8 | ||
|
|
80fc862547 | ||
|
|
6cdc035b2f | ||
|
|
e1e3516397 | ||
|
|
bd5fc4cb1b | ||
|
|
a570c00251 | ||
|
|
3fa2086681 | ||
|
|
8e65413b99 | ||
|
|
8ca40070a4 | ||
|
|
f9b811ce83 | ||
|
|
9ac3879b06 | ||
|
|
37d3e4feaa | ||
|
|
43ec350cd2 | ||
|
|
63b04a687a | ||
|
|
9efa02afb6 | ||
|
|
3a6e58109e | ||
|
|
5ac6ec5496 | ||
|
|
eb22f0101e | ||
|
|
e4bff315eb | ||
|
|
001f6f9719 | ||
|
|
e0b302d651 | ||
|
|
fa2511f71c | ||
|
|
edf1bf1106 | ||
|
|
88dfc49683 | ||
|
|
9dec612cd5 | ||
|
|
02d966d914 | ||
|
|
5b5f6e329c | ||
|
|
4e4a2f8ed3 | ||
|
|
32bd65a87f | ||
|
|
318206d41d | ||
|
|
535212c69e | ||
|
|
1d42e9ad55 | ||
|
|
78f354beb8 | ||
|
|
e012f046bc | ||
|
|
f63b7b079d | ||
|
|
d530f9332c | ||
|
|
10bc86ba10 | ||
|
|
15b608f74c | ||
|
|
7c52af0dec | ||
|
|
cd97237c59 | ||
|
|
965e9767e5 | ||
|
|
41a7000745 | ||
|
|
9cdc1ef6c2 | ||
|
|
4db81065ee | ||
|
|
4653e8aec0 | ||
|
|
ac002b6338 | ||
|
|
9eea3a673a | ||
|
|
d6d2f5ced2 | ||
|
|
887e086890 | ||
|
|
8602d1ba17 | ||
|
|
dd90135944 | ||
|
|
612701a706 | ||
|
|
503532cf77 | ||
|
|
6c0e522922 | ||
|
|
9d37276986 | ||
|
|
5a4cd09938 | ||
|
|
c32fe26b8d | ||
|
|
2c3c4ec323 | ||
|
|
f451a7ad79 | ||
|
|
07953b36b0 | ||
|
|
387c69b194 | ||
|
|
a9d9af53e9 | ||
|
|
8a07f1202c | ||
|
|
41b65af6e2 | ||
|
|
884842cd6c | ||
|
|
8076d66ae5 | ||
|
|
64e3ceec3b | ||
|
|
672cdfa57a | ||
|
|
e39f33e41b | ||
|
|
6667440aaf | ||
|
|
ab5c7e6863 | ||
|
|
08c386f363 | ||
|
|
937a672879 | ||
|
|
513995f57d | ||
|
|
db6fd6db3e | ||
|
|
da930affd2 | ||
|
|
996836b67e | ||
|
|
fc7678c115 | ||
|
|
b371dc2d1e | ||
|
|
56e9454f1f | ||
|
|
d67daa8314 | ||
|
|
f0120e90b6 | ||
|
|
ec4558be29 | ||
|
|
685ab357cc | ||
|
|
5792f30175 | ||
|
|
24443b6764 | ||
|
|
154edf0427 | ||
|
|
4778cf88e2 | ||
|
|
38bd4f65d0 | ||
|
|
0b808f6428 | ||
|
|
b2bc2e1173 | ||
|
|
80787ff7ef | ||
|
|
b92a89f325 | ||
|
|
902292f776 | ||
|
|
3dcf098468 | ||
|
|
d89f0965aa | ||
|
|
c8d98f4787 | ||
|
|
0207b46d70 | ||
|
|
aa2a9fbedb | ||
|
|
3596b4feda | ||
|
|
51deeff72e | ||
|
|
4c227cc6bd | ||
|
|
2426657daa | ||
|
|
e1b03d0235 | ||
|
|
f1b3e9df1e | ||
|
|
fcc87edb71 | ||
|
|
8b464331ba | ||
|
|
9f57920566 | ||
|
|
933ca9ddd8 |
10
.github/workflows/build.yml
vendored
10
.github/workflows/build.yml
vendored
@@ -9,11 +9,11 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
options:
|
||||
- '-mb braces'
|
||||
- '--ie -c'
|
||||
- '-mc'
|
||||
- '-p acorn --toplevel -mco spidermonkey'
|
||||
- '--toplevel -mc passes=3,pure_getters,unsafe'
|
||||
- '-mb braces'
|
||||
- '--toplevel -mc'
|
||||
- '-p acorn -mco spidermonkey'
|
||||
- '-mc passes=3,pure_getters,unsafe'
|
||||
script:
|
||||
- acorn.sh
|
||||
- bootstrap.sh
|
||||
@@ -50,7 +50,7 @@ jobs:
|
||||
OPTIONS: ${{ matrix.options }}
|
||||
SCRIPT: ${{ matrix.script }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
- name: Perform uglify, build & test
|
||||
shell: bash
|
||||
run: |
|
||||
|
||||
7
.github/workflows/ci.yml
vendored
7
.github/workflows/ci.yml
vendored
@@ -7,7 +7,7 @@ jobs:
|
||||
test:
|
||||
strategy:
|
||||
matrix:
|
||||
node: [ '0.10', '0.12', '4', '6', '8', '10', '12', '14', '16', latest ]
|
||||
node: [ '0.10', '0.12', '4', '6', '8', '10', '12', '14', '16', '18', '20' ]
|
||||
os: [ ubuntu-latest, windows-latest ]
|
||||
script: [ compress, mocha, release/benchmark, release/jetstream ]
|
||||
name: ${{ matrix.node }} ${{ matrix.os }} ${{ matrix.script }}
|
||||
@@ -15,9 +15,10 @@ jobs:
|
||||
env:
|
||||
NODE: ${{ matrix.node }}
|
||||
TYPE: ${{ matrix.script }}
|
||||
UGLIFY_GITHUB_LAG: 10000
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/cache@v2
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/cache@v4
|
||||
with:
|
||||
path: tmp
|
||||
key: tmp ${{ matrix.script }}
|
||||
|
||||
18
.github/workflows/moz.yml
vendored
Normal file
18
.github/workflows/moz.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
name: ESTree
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches: [ master ]
|
||||
jobs:
|
||||
test:
|
||||
name: fuzzing
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
NODE: latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Perform tests
|
||||
shell: bash
|
||||
run: |
|
||||
. ./test/release/install.sh
|
||||
node test/mozilla-ast.js 5000
|
||||
2
.github/workflows/ufuzz.yml
vendored
2
.github/workflows/ufuzz.yml
vendored
@@ -32,7 +32,7 @@ jobs:
|
||||
env:
|
||||
NODE: ${{ matrix.node }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
- name: Perform fuzzing
|
||||
shell: bash
|
||||
run: |
|
||||
|
||||
@@ -3,7 +3,7 @@ Contributing
|
||||
|
||||
## Documentation
|
||||
|
||||
Every new feature and API change should be accompanied by a README additon.
|
||||
Every new feature and API change should be accompanied by a README addition.
|
||||
|
||||
## Testing
|
||||
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
UglifyJS is released under the BSD license:
|
||||
|
||||
Copyright 2012-2019 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
||||
Copyright 2012-2024 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
|
||||
87
README.md
87
README.md
@@ -54,8 +54,6 @@ a double dash to prevent input files being used as option arguments:
|
||||
modules and Userscripts that may
|
||||
be anonymous function wrapped (IIFE)
|
||||
by the .user.js engine `caller`.
|
||||
`expression` Parse a single expression, rather than
|
||||
a program (for parsing JSON).
|
||||
`spidermonkey` Assume input files are SpiderMonkey
|
||||
AST format (as JSON).
|
||||
-c, --compress [options] Enable compressor/specify compressor options:
|
||||
@@ -111,6 +109,8 @@ a double dash to prevent input files being used as option arguments:
|
||||
-d, --define <expr>[=value] Global definitions.
|
||||
-e, --enclose [arg[:value]] Embed everything in a big function, with configurable
|
||||
argument(s) & value(s).
|
||||
--expression Parse a single expression, rather than a program
|
||||
(for parsing JSON).
|
||||
--ie Support non-standard Internet Explorer.
|
||||
Equivalent to setting `ie: true` in `minify()`
|
||||
for `compress`, `mangle` and `output` options.
|
||||
@@ -119,6 +119,8 @@ a double dash to prevent input files being used as option arguments:
|
||||
--keep-fnames Do not mangle/drop function names. Useful for
|
||||
code relying on Function.prototype.name.
|
||||
--module Process input as ES module (implies --toplevel)
|
||||
--no-module Avoid optimizations which may alter runtime behavior
|
||||
under prior versions of JavaScript.
|
||||
--name-cache <file> File to hold mangled name mappings.
|
||||
--self Build UglifyJS as a library (implies --wrap UglifyJS)
|
||||
--source-map [options] Enable source map/specify source map options:
|
||||
@@ -327,7 +329,7 @@ unquoted style (`o.foo`). Example:
|
||||
// stuff.js
|
||||
var o = {
|
||||
"foo": 1,
|
||||
bar: 3
|
||||
bar: 3,
|
||||
};
|
||||
o.foo += o.bar;
|
||||
console.log(o.foo);
|
||||
@@ -339,6 +341,16 @@ $ uglifyjs stuff.js --mangle-props keep_quoted -c -m
|
||||
var o={foo:1,o:3};o.foo+=o.o,console.log(o.foo);
|
||||
```
|
||||
|
||||
If the minified output will be processed again by UglifyJS, consider specifying
|
||||
`keep_quoted_props` so the same property names are preserved:
|
||||
|
||||
```bash
|
||||
$ uglifyjs stuff.js --mangle-props keep_quoted -c -m -O keep_quoted_props
|
||||
```
|
||||
```javascript
|
||||
var o={"foo":1,o:3};o.foo+=o.o,console.log(o.foo);
|
||||
```
|
||||
|
||||
### Debugging property name mangling
|
||||
|
||||
You can also pass `--mangle-props debug` in order to mangle property names
|
||||
@@ -504,6 +516,8 @@ if (result.error) throw result.error;
|
||||
- `compress` (default: `{}`) — pass `false` to skip compressing entirely.
|
||||
Pass an object to specify custom [compress options](#compress-options).
|
||||
|
||||
- `expression` (default: `false`) — parse as a single expression, e.g. JSON.
|
||||
|
||||
- `ie` (default: `false`) — enable workarounds for Internet Explorer bugs.
|
||||
|
||||
- `keep_fargs` (default: `false`) — pass `true` to prevent discarding or mangling
|
||||
@@ -518,9 +532,9 @@ if (result.error) throw result.error;
|
||||
- `mangle.properties` (default: `false`) — a subcategory of the mangle option.
|
||||
Pass an object to specify custom [mangle property options](#mangle-properties-options).
|
||||
|
||||
- `module` (default: `false`) — set to `true` if you wish to process input as
|
||||
ES module, i.e. implicit `"use strict";` and support for top-level `await`,
|
||||
alongside with `toplevel` enabled.
|
||||
- `module` (default: `true`) — process input as ES module, i.e. implicit
|
||||
`"use strict";` and support for top-level `await`. When explicitly specified,
|
||||
also enables `toplevel`.
|
||||
|
||||
- `nameCache` (default: `null`) — pass an empty object `{}` or a previously
|
||||
used `nameCache` object if you wish to cache mangled variable and
|
||||
@@ -633,10 +647,8 @@ to be `false` and all symbol names will be omitted.
|
||||
|
||||
- `bare_returns` (default: `false`) — support top level `return` statements
|
||||
|
||||
- `expression` (default: `false`) — parse as a single expression, e.g. JSON
|
||||
|
||||
- `html5_comments` (default: `true`) — process HTML comment as workaround for
|
||||
browsers which do not recognise `<script>` tags
|
||||
browsers which do not recognize `<script>` tags
|
||||
|
||||
- `module` (default: `false`) — set to `true` if you wish to process input as
|
||||
ES module, i.e. implicit `"use strict";` and support for top-level `await`.
|
||||
@@ -740,10 +752,10 @@ to be `false` and all symbol names will be omitted.
|
||||
- `merge_vars` (default: `true`) — combine and reuse variables.
|
||||
|
||||
- `module` (default: `false`) — set to `true` if you wish to process input as
|
||||
ES module, i.e. implicit `"use strict";` alongside with `toplevel` enabled.
|
||||
ES module, i.e. implicit `"use strict";`.
|
||||
|
||||
- `negate_iife` (default: `true`) — negate "Immediately-Called Function Expressions"
|
||||
where the return value is discarded, to avoid the parens that the
|
||||
where the return value is discarded, to avoid the parentheses that the
|
||||
code generator would insert.
|
||||
|
||||
- `objects` (default: `true`) — compact duplicate keys in object literals.
|
||||
@@ -767,11 +779,11 @@ to be `false` and all symbol names will be omitted.
|
||||
overhead (compression will be slower). Make sure symbols under `pure_funcs`
|
||||
are also under `mangle.reserved` to avoid mangling.
|
||||
|
||||
- `pure_getters` (default: `"strict"`) — If you pass `true` for
|
||||
this, UglifyJS will assume that object property access
|
||||
(e.g. `foo.bar` or `foo["bar"]`) doesn't have any side effects.
|
||||
Specify `"strict"` to treat `foo.bar` as side-effect-free only when
|
||||
`foo` is certain to not throw, i.e. not `null` or `undefined`.
|
||||
- `pure_getters` (default: `"strict"`) — Pass `true` for UglifyJS to assume that
|
||||
object property access (e.g. `foo.bar` or `a[42]`) does not throw exception or
|
||||
alter program states via getter function. Pass `"strict"` to allow dropping or
|
||||
reordering `foo.bar` only if `foo` is not `null` or `undefined` and is safe to
|
||||
access as a variable. Pass `false` to retain all property accesses.
|
||||
|
||||
- `reduce_funcs` (default: `true`) — Allows single-use functions to be
|
||||
inlined as function expressions when permissible allowing further
|
||||
@@ -841,7 +853,7 @@ to be `false` and all symbol names will be omitted.
|
||||
- `unused` (default: `true`) — drop unreferenced functions and variables (simple
|
||||
direct variable assignments do not count as references unless set to `"keep_assign"`)
|
||||
|
||||
- `varify` (default: `true`) — convert block-scoped declaractions into `var`
|
||||
- `varify` (default: `true`) — convert block-scoped declarations into `var`
|
||||
whenever safe to do so
|
||||
|
||||
- `yields` (default: `true`) — apply optimizations to `yield` expressions
|
||||
@@ -881,12 +893,15 @@ UglifyJS.minify(code, { mangle: { toplevel: true } }).code;
|
||||
|
||||
### Mangle properties options
|
||||
|
||||
- `builtins` (default: `false`) — Use `true` to allow the mangling of builtin
|
||||
DOM properties. Not recommended to override this setting.
|
||||
- `builtins` (default: `false`) — Use `true` to allow the mangling of built-in
|
||||
properties of JavaScript API. Not recommended to override this setting.
|
||||
|
||||
- `debug` (default: `false`) — Mangle names with the original name still present.
|
||||
Pass an empty string `""` to enable, or a non-empty string to set the debug suffix.
|
||||
|
||||
- `domprops` (default: `false`) — Use `true` to allow the mangling of properties
|
||||
commonly found in Document Object Model. Not recommended to override this setting.
|
||||
|
||||
- `keep_fargs` (default: `false`) — Use `true` to prevent mangling of function
|
||||
arguments.
|
||||
|
||||
@@ -912,9 +927,8 @@ can pass additional arguments that control the code output:
|
||||
regexps (affects directives with non-ascii characters becoming invalid)
|
||||
|
||||
- `beautify` (default: `true`) — whether to actually beautify the output.
|
||||
Passing `-b` will set this to true, but you might need to pass `-b` even
|
||||
when you want to generate minified code, in order to specify additional
|
||||
arguments, so you can use `-b beautify=false` to override it.
|
||||
Passing `-b` will set this to true. Use `-O` if you want to generate minified
|
||||
code and specify additional arguments.
|
||||
|
||||
- `braces` (default: `false`) — always insert braces in `if`, `for`,
|
||||
`do`, `while` or `with` statements, even if their body is a single
|
||||
@@ -930,6 +944,9 @@ can pass additional arguments that control the code output:
|
||||
}
|
||||
```
|
||||
|
||||
- `extendscript` (default: `false`) — enable workarounds for Adobe ExtendScript
|
||||
bugs
|
||||
|
||||
- `galio` (default: `false`) — enable workarounds for ANT Galio bugs
|
||||
|
||||
- `indent_level` (default: `4`) — indent by specified number of spaces or the
|
||||
@@ -1359,7 +1376,7 @@ To allow for better optimizations, the compiler makes various assumptions:
|
||||
// SyntaxError: The left-hand side of a for-of loop may not be 'async'.
|
||||
```
|
||||
UglifyJS may modify the input which in turn may suppress those errors.
|
||||
- Later versions of Chrome and Node.js will give incorrect results with the
|
||||
- Some versions of Chrome and Node.js will give incorrect results with the
|
||||
following:
|
||||
```javascript
|
||||
console.log({
|
||||
@@ -1368,9 +1385,15 @@ To allow for better optimizations, the compiler makes various assumptions:
|
||||
return "FAIL";
|
||||
},
|
||||
[42]: "PASS",
|
||||
}[42], {
|
||||
...console,
|
||||
get 42() {
|
||||
return "FAIL";
|
||||
},
|
||||
42: "PASS",
|
||||
}[42]);
|
||||
// Expected: "PASS"
|
||||
// Actual: "FAIL"
|
||||
// Expected: "PASS PASS"
|
||||
// Actual: "PASS FAIL"
|
||||
```
|
||||
UglifyJS may modify the input which in turn may suppress those errors.
|
||||
- Earlier versions of JavaScript will throw `TypeError` with the following:
|
||||
@@ -1440,3 +1463,17 @@ To allow for better optimizations, the compiler makes various assumptions:
|
||||
// Actual: TypeError: invalid assignment to const 'f'
|
||||
```
|
||||
UglifyJS may modify the input which in turn may suppress those errors.
|
||||
- Adobe ExtendScript will give incorrect results with the following:
|
||||
```javascript
|
||||
alert(true ? "PASS" : false ? "FAIL" : null);
|
||||
// Expected: "PASS"
|
||||
// Actual: "FAIL"
|
||||
```
|
||||
UglifyJS may modify the input which in turn may suppress those errors.
|
||||
- Adobe ExtendScript will give incorrect results with the following:
|
||||
```javascript
|
||||
alert(42 ? null ? "FAIL" : "PASS" : "FAIL");
|
||||
// Expected: "PASS"
|
||||
// Actual: SyntaxError: Expected: :
|
||||
```
|
||||
UglifyJS may modify the input which in turn may suppress those errors.
|
||||
|
||||
100
bin/uglifyjs
100
bin/uglifyjs
@@ -104,10 +104,12 @@ function process_option(name, no_value) {
|
||||
" --config-file <file> Read minify() options from JSON file.",
|
||||
" -d, --define <expr>[=value] Global definitions.",
|
||||
" -e, --enclose [arg[,...][:value[,...]]] Embed everything in a big function, with configurable argument(s) & value(s).",
|
||||
" --expression Parse a single expression, rather than a program.",
|
||||
" --ie Support non-standard Internet Explorer.",
|
||||
" --keep-fargs Do not mangle/drop function arguments.",
|
||||
" --keep-fnames Do not mangle/drop function names. Useful for code relying on Function.prototype.name.",
|
||||
" --module Process input as ES module (implies --toplevel)",
|
||||
" --module Process input as ES module (implies --toplevel).",
|
||||
" --no-module Process input with improved JavaScript compatibility.",
|
||||
" --name-cache <file> File to hold mangled name mappings.",
|
||||
" --rename Force symbol expansion.",
|
||||
" --no-rename Disable symbol expansion.",
|
||||
@@ -151,9 +153,9 @@ function process_option(name, no_value) {
|
||||
options[name] = read_value();
|
||||
break;
|
||||
case "annotations":
|
||||
case "expression":
|
||||
case "ie":
|
||||
case "ie8":
|
||||
case "module":
|
||||
case "timings":
|
||||
case "toplevel":
|
||||
case "v8":
|
||||
@@ -199,6 +201,12 @@ function process_option(name, no_value) {
|
||||
if (typeof options.mangle != "object") options.mangle = {};
|
||||
options.mangle.properties = parse_js(read_value(), options.mangle.properties);
|
||||
break;
|
||||
case "module":
|
||||
options.module = true;
|
||||
break;
|
||||
case "no-module":
|
||||
options.module = false;
|
||||
break;
|
||||
case "name-cache":
|
||||
nameCache = read_value(true);
|
||||
options.nameCache = JSON.parse(read_file(nameCache, "{}"));
|
||||
@@ -236,17 +244,6 @@ if (specified["beautify"] && specified["output-opts"]) fatal("--beautify cannot
|
||||
[ "compress", "mangle" ].forEach(function(name) {
|
||||
if (!(name in options)) options[name] = false;
|
||||
});
|
||||
if (options.mangle && options.mangle.properties) {
|
||||
if (options.mangle.properties.domprops) {
|
||||
delete options.mangle.properties.domprops;
|
||||
} else {
|
||||
if (typeof options.mangle.properties != "object") options.mangle.properties = {};
|
||||
if (!Array.isArray(options.mangle.properties.reserved)) options.mangle.properties.reserved = [];
|
||||
require("../tools/domprops").forEach(function(name) {
|
||||
UglifyJS.push_uniq(options.mangle.properties.reserved, name);
|
||||
});
|
||||
}
|
||||
}
|
||||
if (/^ast|spidermonkey$/.test(output)) {
|
||||
if (typeof options.output != "object") options.output = {};
|
||||
options.output.ast = true;
|
||||
@@ -276,6 +273,8 @@ if (specified["self"]) {
|
||||
if (paths.length) UglifyJS.AST_Node.warn("Ignoring input files since --self was passed");
|
||||
if (!options.wrap) options.wrap = "UglifyJS";
|
||||
paths = UglifyJS.FILES;
|
||||
} else if (paths.length) {
|
||||
paths = simple_glob(paths);
|
||||
}
|
||||
if (specified["in-situ"]) {
|
||||
if (output && output != "spidermonkey" || specified["reduce-test"] || specified["self"]) {
|
||||
@@ -290,7 +289,7 @@ if (specified["in-situ"]) {
|
||||
run();
|
||||
});
|
||||
} else if (paths.length) {
|
||||
simple_glob(paths).forEach(function(name) {
|
||||
paths.forEach(function(name) {
|
||||
files[convert_path(name)] = read_file(name);
|
||||
});
|
||||
run();
|
||||
@@ -302,9 +301,19 @@ if (specified["in-situ"]) {
|
||||
process.stdin.setEncoding("utf8");
|
||||
process.stdin.once("data", function() {
|
||||
clearTimeout(timerId);
|
||||
}).on("data", function(chunk) {
|
||||
}).on("data", process.stdin.isTTY ? function(chunk) {
|
||||
// emulate console input termination via Ctrl+D / Ctrl+Z
|
||||
var match = /[\x04\x1a]\r?\n?$/.exec(chunk);
|
||||
if (match) {
|
||||
chunks.push(chunk.slice(0, -match[0].length));
|
||||
process.stdin.pause();
|
||||
process.stdin.emit("end");
|
||||
} else {
|
||||
chunks.push(chunk);
|
||||
}
|
||||
} : function(chunk) {
|
||||
chunks.push(chunk);
|
||||
}).on("end", function() {
|
||||
}).once("end", function() {
|
||||
files = { STDIN: chunks.join("") };
|
||||
run();
|
||||
});
|
||||
@@ -489,33 +498,42 @@ function fatal(message) {
|
||||
|
||||
// A file glob function that only supports "*" and "?" wildcards in the basename.
|
||||
// Example: "foo/bar/*baz??.*.js"
|
||||
// Argument `glob` may be a string or an array of strings.
|
||||
// Argument `paths` must be an array of strings.
|
||||
// Returns an array of strings. Garbage in, garbage out.
|
||||
function simple_glob(glob) {
|
||||
if (Array.isArray(glob)) {
|
||||
return [].concat.apply([], glob.map(simple_glob));
|
||||
}
|
||||
if (glob.match(/\*|\?/)) {
|
||||
var dir = path.dirname(glob);
|
||||
try {
|
||||
var entries = fs.readdirSync(dir);
|
||||
} catch (ex) {}
|
||||
if (entries) {
|
||||
var pattern = "^" + path.basename(glob)
|
||||
.replace(/[.+^$[\]\\(){}]/g, "\\$&")
|
||||
.replace(/\*/g, "[^/\\\\]*")
|
||||
.replace(/\?/g, "[^/\\\\]") + "$";
|
||||
var mod = process.platform === "win32" ? "i" : "";
|
||||
var rx = new RegExp(pattern, mod);
|
||||
var results = entries.sort().filter(function(name) {
|
||||
return rx.test(name);
|
||||
}).map(function(name) {
|
||||
return path.join(dir, name);
|
||||
});
|
||||
if (results.length) return results;
|
||||
function simple_glob(paths) {
|
||||
return paths.reduce(function(paths, glob) {
|
||||
if (/\*|\?/.test(glob)) {
|
||||
var dir = path.dirname(glob);
|
||||
try {
|
||||
var entries = fs.readdirSync(dir).filter(function(name) {
|
||||
try {
|
||||
return fs.statSync(path.join(dir, name)).isFile();
|
||||
} catch (ex) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
} catch (ex) {}
|
||||
if (entries) {
|
||||
var pattern = "^" + path.basename(glob)
|
||||
.replace(/[.+^$[\]\\(){}]/g, "\\$&")
|
||||
.replace(/\*/g, "[^/\\\\]*")
|
||||
.replace(/\?/g, "[^/\\\\]") + "$";
|
||||
var mod = process.platform === "win32" ? "i" : "";
|
||||
var rx = new RegExp(pattern, mod);
|
||||
var results = entries.filter(function(name) {
|
||||
return rx.test(name);
|
||||
}).sort().map(function(name) {
|
||||
return path.join(dir, name);
|
||||
});
|
||||
if (results.length) {
|
||||
[].push.apply(paths, results);
|
||||
return paths;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return [ glob ];
|
||||
paths.push(glob);
|
||||
return paths;
|
||||
}, []);
|
||||
}
|
||||
|
||||
function read_file(path, default_value) {
|
||||
|
||||
287
lib/ast.js
287
lib/ast.js
@@ -109,6 +109,9 @@ var AST_Node = DEFNODE("Node", "start end", {
|
||||
start: "[AST_Token] The first token of this node",
|
||||
end: "[AST_Token] The last token of this node"
|
||||
},
|
||||
equals: function(node) {
|
||||
return this.TYPE == node.TYPE && this._equals(node);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
visitor.visit(this);
|
||||
},
|
||||
@@ -125,12 +128,7 @@ var AST_Node = DEFNODE("Node", "start end", {
|
||||
var marker = {};
|
||||
this.walk(new TreeWalker(function(node) {
|
||||
if (node.validate_visited === marker) {
|
||||
throw new Error(string_template("cannot reuse {type} from [{file}:{line},{col}]", {
|
||||
type: "AST_" + node.TYPE,
|
||||
file: node.start.file,
|
||||
line: node.start.line,
|
||||
col: node.start.col,
|
||||
}));
|
||||
throw new Error(string_template("cannot reuse AST_{TYPE} from [{start}]", node));
|
||||
}
|
||||
node.validate_visited = marker;
|
||||
}));
|
||||
@@ -138,6 +136,7 @@ var AST_Node = DEFNODE("Node", "start end", {
|
||||
}, null);
|
||||
|
||||
DEF_BITPROPS(AST_Node, [
|
||||
// AST_Node
|
||||
"_optimized",
|
||||
"_squeezed",
|
||||
// AST_Call
|
||||
@@ -170,8 +169,8 @@ DEF_BITPROPS(AST_Node, [
|
||||
"private",
|
||||
// AST_Call
|
||||
"pure",
|
||||
// AST_Assign
|
||||
"redundant",
|
||||
// AST_Node
|
||||
"single_use",
|
||||
// AST_ClassProperty
|
||||
"static",
|
||||
// AST_Call
|
||||
@@ -231,6 +230,24 @@ AST_Node.disable_validation = function() {
|
||||
while (restore = restore_transforms.pop()) restore();
|
||||
};
|
||||
|
||||
function all_equals(k, l) {
|
||||
return k.length == l.length && all(k, function(m, i) {
|
||||
return m.equals(l[i]);
|
||||
});
|
||||
}
|
||||
|
||||
function list_equals(s, t) {
|
||||
return s.length == t.length && all(s, function(u, i) {
|
||||
return u == t[i];
|
||||
});
|
||||
}
|
||||
|
||||
function prop_equals(u, v) {
|
||||
if (u === v) return true;
|
||||
if (u == null) return v == null;
|
||||
return u instanceof AST_Node && v instanceof AST_Node && u.equals(v);
|
||||
}
|
||||
|
||||
/* -----[ statements ]----- */
|
||||
|
||||
var AST_Statement = DEFNODE("Statement", null, {
|
||||
@@ -242,6 +259,7 @@ var AST_Statement = DEFNODE("Statement", null, {
|
||||
|
||||
var AST_Debugger = DEFNODE("Debugger", null, {
|
||||
$documentation: "Represents a debugger statement",
|
||||
_equals: return_true,
|
||||
}, AST_Statement);
|
||||
|
||||
var AST_Directive = DEFNODE("Directive", "quote value", {
|
||||
@@ -250,6 +268,9 @@ var AST_Directive = DEFNODE("Directive", "quote value", {
|
||||
quote: "[string?] the original quote character",
|
||||
value: "[string] The value of this directive as a plain string (it's not an AST_String!)",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.value == node.value;
|
||||
},
|
||||
_validate: function() {
|
||||
if (this.quote != null) {
|
||||
if (typeof this.quote != "string") throw new Error("quote must be string");
|
||||
@@ -260,7 +281,8 @@ var AST_Directive = DEFNODE("Directive", "quote value", {
|
||||
}, AST_Statement);
|
||||
|
||||
var AST_EmptyStatement = DEFNODE("EmptyStatement", null, {
|
||||
$documentation: "The empty statement (empty block or simply a semicolon)"
|
||||
$documentation: "The empty statement (empty block or simply a semicolon)",
|
||||
_equals: return_true,
|
||||
}, AST_Statement);
|
||||
|
||||
function is_statement(node) {
|
||||
@@ -291,6 +313,9 @@ var AST_SimpleStatement = DEFNODE("SimpleStatement", "body", {
|
||||
$propdoc: {
|
||||
body: "[AST_Node] an expression node (should not be instanceof AST_Statement)",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.body.equals(node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -305,7 +330,7 @@ var AST_SimpleStatement = DEFNODE("SimpleStatement", "body", {
|
||||
var AST_BlockScope = DEFNODE("BlockScope", "_var_names enclosed functions make_def parent_scope variables", {
|
||||
$documentation: "Base class for all statements introducing a lexical scope",
|
||||
$propdoc: {
|
||||
enclosed: "[SymbolDef*/S] a list of all symbol definitions that are accessed from this scope or any subscopes",
|
||||
enclosed: "[SymbolDef*/S] a list of all symbol definitions that are accessed from this scope or any inner scopes",
|
||||
functions: "[Dictionary/S] like `variables`, but only lists function declarations",
|
||||
parent_scope: "[AST_Scope?/S] link to the parent scope",
|
||||
variables: "[Dictionary/S] a map of name ---> SymbolDef for all variables/functions defined in this scope",
|
||||
@@ -342,6 +367,9 @@ var AST_Block = DEFNODE("Block", "body", {
|
||||
$propdoc: {
|
||||
body: "[AST_Statement*] an array of statements"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return all_equals(this.body, node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -376,6 +404,10 @@ var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", {
|
||||
$propdoc: {
|
||||
label: "[AST_Label] a label definition"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.label.equals(node.label)
|
||||
&& this.body.equals(node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -417,6 +449,10 @@ var AST_DWLoop = DEFNODE("DWLoop", "condition", {
|
||||
$propdoc: {
|
||||
condition: "[AST_Node] the loop condition. Should not be instanceof AST_Statement"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.body.equals(node.body)
|
||||
&& this.condition.equals(node.condition);
|
||||
},
|
||||
_validate: function() {
|
||||
if (this.TYPE == "DWLoop") throw new Error("should not instantiate AST_DWLoop");
|
||||
must_be_expression(this, "condition");
|
||||
@@ -431,7 +467,7 @@ var AST_Do = DEFNODE("Do", null, {
|
||||
node.body.walk(visitor);
|
||||
node.condition.walk(visitor);
|
||||
});
|
||||
}
|
||||
},
|
||||
}, AST_DWLoop);
|
||||
|
||||
var AST_While = DEFNODE("While", null, {
|
||||
@@ -442,7 +478,7 @@ var AST_While = DEFNODE("While", null, {
|
||||
node.condition.walk(visitor);
|
||||
node.body.walk(visitor);
|
||||
});
|
||||
}
|
||||
},
|
||||
}, AST_DWLoop);
|
||||
|
||||
var AST_For = DEFNODE("For", "init condition step", {
|
||||
@@ -452,6 +488,12 @@ var AST_For = DEFNODE("For", "init condition step", {
|
||||
condition: "[AST_Node?] the `for` termination clause, or null if empty",
|
||||
step: "[AST_Node?] the `for` update clause, or null if empty"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.init, node.init)
|
||||
&& prop_equals(this.condition, node.condition)
|
||||
&& prop_equals(this.step, node.step)
|
||||
&& this.body.equals(node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -479,6 +521,11 @@ var AST_ForEnumeration = DEFNODE("ForEnumeration", "init object", {
|
||||
init: "[AST_Node] the assignment target during iteration",
|
||||
object: "[AST_Node] the object to iterate over"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.init.equals(node.init)
|
||||
&& this.object.equals(node.object)
|
||||
&& this.body.equals(node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -519,6 +566,10 @@ var AST_With = DEFNODE("With", "expression", {
|
||||
$propdoc: {
|
||||
expression: "[AST_Node] the `with` expression"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.expression.equals(node.expression)
|
||||
&& this.body.equals(node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -621,6 +672,13 @@ var AST_Lambda = DEFNODE("Lambda", "argnames length_read rest safe_ids uses_argu
|
||||
});
|
||||
if (this.rest) this.rest.walk(tw);
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.rest, node.rest)
|
||||
&& prop_equals(this.name, node.name)
|
||||
&& prop_equals(this.value, node.value)
|
||||
&& all_equals(this.argnames, node.argnames)
|
||||
&& all_equals(this.body, node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -831,6 +889,11 @@ var AST_Class = DEFNODE("Class", "extends name properties", {
|
||||
extends: "[AST_Node?] the super class, or null if not specified",
|
||||
properties: "[AST_ClassProperty*] array of class properties",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.name, node.name)
|
||||
&& prop_equals(this.extends, node.extends)
|
||||
&& all_equals(this.properties, node.properties);
|
||||
},
|
||||
resolve: function(def_class) {
|
||||
return def_class ? this : this.parent_scope.resolve();
|
||||
},
|
||||
@@ -883,6 +946,12 @@ var AST_ClassProperty = DEFNODE("ClassProperty", "key private static value", {
|
||||
static: "[boolean] whether this is a static property",
|
||||
value: "[AST_Node?] property value (AST_Accessor for getters/setters, AST_LambdaExpression for methods, null if not specified for fields)",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return !this.private == !node.private
|
||||
&& !this.static == !node.static
|
||||
&& prop_equals(this.key, node.key)
|
||||
&& prop_equals(this.value, node.value);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -959,6 +1028,9 @@ var AST_Exit = DEFNODE("Exit", "value", {
|
||||
$propdoc: {
|
||||
value: "[AST_Node?] the value returned or thrown by this statement; could be null for AST_Return"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.value, node.value);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -989,6 +1061,9 @@ var AST_LoopControl = DEFNODE("LoopControl", "label", {
|
||||
$propdoc: {
|
||||
label: "[AST_LabelRef?] the label, or null if none",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.label, node.label);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1019,6 +1094,11 @@ var AST_If = DEFNODE("If", "condition alternative", {
|
||||
condition: "[AST_Node] the `if` condition",
|
||||
alternative: "[AST_Statement?] the `else` part, or null if not present"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.body.equals(node.body)
|
||||
&& this.condition.equals(node.condition)
|
||||
&& prop_equals(this.alternative, node.alternative);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1042,6 +1122,10 @@ var AST_Switch = DEFNODE("Switch", "expression", {
|
||||
$propdoc: {
|
||||
expression: "[AST_Node] the `switch` “discriminant”"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.expression.equals(node.expression)
|
||||
&& all_equals(this.body, node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1073,6 +1157,10 @@ var AST_Case = DEFNODE("Case", "expression", {
|
||||
$propdoc: {
|
||||
expression: "[AST_Node] the `case` expression"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.expression.equals(node.expression)
|
||||
&& all_equals(this.body, node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1093,6 +1181,11 @@ var AST_Try = DEFNODE("Try", "bcatch bfinally", {
|
||||
bcatch: "[AST_Catch?] the catch block, or null if not present",
|
||||
bfinally: "[AST_Finally?] the finally block, or null if not present"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return all_equals(this.body, node.body)
|
||||
&& prop_equals(this.bcatch, node.bcatch)
|
||||
&& prop_equals(this.bfinally, node.bfinally);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1116,6 +1209,10 @@ var AST_Catch = DEFNODE("Catch", "argname", {
|
||||
$propdoc: {
|
||||
argname: "[(AST_Destructured|AST_SymbolCatch)?] symbol for the exception, or null if not present",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.argname, node.argname)
|
||||
&& all_equals(this.body, node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1141,6 +1238,9 @@ var AST_Definitions = DEFNODE("Definitions", "definitions", {
|
||||
$propdoc: {
|
||||
definitions: "[AST_VarDef*] array of variable definitions"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return all_equals(this.definitions, node.definitions);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1197,6 +1297,10 @@ var AST_VarDef = DEFNODE("VarDef", "name value", {
|
||||
name: "[AST_Destructured|AST_SymbolVar] name of the variable",
|
||||
value: "[AST_Node?] initializer, or null of there's no initializer",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.name.equals(node.name)
|
||||
&& prop_equals(this.value, node.value);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1216,6 +1320,9 @@ var AST_ExportDeclaration = DEFNODE("ExportDeclaration", "body", {
|
||||
$propdoc: {
|
||||
body: "[AST_DefClass|AST_Definitions|AST_LambdaDefinition] the statement to export",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.body.equals(node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1236,6 +1343,9 @@ var AST_ExportDefault = DEFNODE("ExportDefault", "body", {
|
||||
$propdoc: {
|
||||
body: "[AST_Node] the default export",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.body.equals(node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1249,29 +1359,29 @@ var AST_ExportDefault = DEFNODE("ExportDefault", "body", {
|
||||
},
|
||||
}, AST_Statement);
|
||||
|
||||
var AST_ExportForeign = DEFNODE("ExportForeign", "aliases keys path quote", {
|
||||
var AST_ExportForeign = DEFNODE("ExportForeign", "aliases keys path", {
|
||||
$documentation: "An `export ... from '...'` statement",
|
||||
$propdoc: {
|
||||
aliases: "[string*] array of aliases to export",
|
||||
keys: "[string*] array of keys to import",
|
||||
path: "[string] the path to import module",
|
||||
quote: "[string?] the original quote character",
|
||||
aliases: "[AST_String*] array of aliases to export",
|
||||
keys: "[AST_String*] array of keys to import",
|
||||
path: "[AST_String] the path to import module",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.path.equals(node.path)
|
||||
&& all_equals(this.aliases, node.aliases)
|
||||
&& all_equals(this.keys, node.keys);
|
||||
},
|
||||
_validate: function() {
|
||||
if (this.aliases.length != this.keys.length) {
|
||||
throw new Error("aliases:key length mismatch: " + this.aliases.length + " != " + this.keys.length);
|
||||
}
|
||||
this.aliases.forEach(function(name) {
|
||||
if (typeof name != "string") throw new Error("aliases must contain string");
|
||||
if (!(name instanceof AST_String)) throw new Error("aliases must contain AST_String");
|
||||
});
|
||||
this.keys.forEach(function(name) {
|
||||
if (typeof name != "string") throw new Error("keys must contain string");
|
||||
if (!(name instanceof AST_String)) throw new Error("keys must contain AST_String");
|
||||
});
|
||||
if (typeof this.path != "string") throw new Error("path must be string");
|
||||
if (this.quote != null) {
|
||||
if (typeof this.quote != "string") throw new Error("quote must be string");
|
||||
if (!/^["']$/.test(this.quote)) throw new Error("invalid quote: " + this.quote);
|
||||
}
|
||||
if (!(this.path instanceof AST_String)) throw new Error("path must be AST_String");
|
||||
},
|
||||
}, AST_Statement);
|
||||
|
||||
@@ -1280,6 +1390,9 @@ var AST_ExportReferences = DEFNODE("ExportReferences", "properties", {
|
||||
$propdoc: {
|
||||
properties: "[AST_SymbolExport*] array of aliases to export",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return all_equals(this.properties, node.properties);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1295,14 +1408,20 @@ var AST_ExportReferences = DEFNODE("ExportReferences", "properties", {
|
||||
},
|
||||
}, AST_Statement);
|
||||
|
||||
var AST_Import = DEFNODE("Import", "all default path properties quote", {
|
||||
var AST_Import = DEFNODE("Import", "all default path properties", {
|
||||
$documentation: "An `import` statement",
|
||||
$propdoc: {
|
||||
all: "[AST_SymbolImport?] the imported namespace, or null if not specified",
|
||||
default: "[AST_SymbolImport?] the alias for default `export`, or null if not specified",
|
||||
path: "[string] the path to import module",
|
||||
path: "[AST_String] the path to import module",
|
||||
properties: "[(AST_SymbolImport*)?] array of aliases, or null if not specified",
|
||||
quote: "[string?] the original quote character",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.path.equals(node.path)
|
||||
&& prop_equals(this.all, node.all)
|
||||
&& prop_equals(this.default, node.default)
|
||||
&& !this.properties == !node.properties
|
||||
&& (!this.properties || all_equals(this.properties, node.properties));
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
@@ -1321,16 +1440,12 @@ var AST_Import = DEFNODE("Import", "all default path properties quote", {
|
||||
}
|
||||
if (this.default != null) {
|
||||
if (!(this.default instanceof AST_SymbolImport)) throw new Error("default must be AST_SymbolImport");
|
||||
if (this.default.key !== "") throw new Error("invalid default key: " + this.default.key);
|
||||
if (this.default.key.value !== "") throw new Error("invalid default key: " + this.default.key.value);
|
||||
}
|
||||
if (typeof this.path != "string") throw new Error("path must be string");
|
||||
if (!(this.path instanceof AST_String)) throw new Error("path must be AST_String");
|
||||
if (this.properties != null) this.properties.forEach(function(node) {
|
||||
if (!(node instanceof AST_SymbolImport)) throw new Error("properties must contain AST_SymbolImport");
|
||||
});
|
||||
if (this.quote != null) {
|
||||
if (typeof this.quote != "string") throw new Error("quote must be string");
|
||||
if (!/^["']$/.test(this.quote)) throw new Error("invalid quote: " + this.quote);
|
||||
}
|
||||
},
|
||||
}, AST_Statement);
|
||||
|
||||
@@ -1340,6 +1455,10 @@ var AST_DefaultValue = DEFNODE("DefaultValue", "name value", {
|
||||
name: "[AST_Destructured|AST_SymbolDeclaration] name of the variable",
|
||||
value: "[AST_Node] value to assign if variable is `undefined`",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.name.equals(node.name)
|
||||
&& this.value.equals(node.value);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1367,6 +1486,11 @@ var AST_Call = DEFNODE("Call", "args expression optional pure terminal", {
|
||||
pure: "[boolean/S] marker for side-effect-free call expression",
|
||||
terminal: "[boolean] whether the chain has ended",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return !this.optional == !node.optional
|
||||
&& this.expression.equals(node.expression)
|
||||
&& all_equals(this.args, node.args);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1393,7 +1517,10 @@ var AST_New = DEFNODE("New", null, {
|
||||
var AST_Sequence = DEFNODE("Sequence", "expressions", {
|
||||
$documentation: "A sequence expression (comma-separated expressions)",
|
||||
$propdoc: {
|
||||
expressions: "[AST_Node*] array of expressions (at least two)"
|
||||
expressions: "[AST_Node*] array of expressions (at least two)",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return all_equals(this.expressions, node.expressions);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
@@ -1422,6 +1549,11 @@ var AST_PropAccess = DEFNODE("PropAccess", "expression optional property termina
|
||||
property: "[AST_Node|string] the property to access. For AST_Dot this is always a plain string, while for AST_Sub it's an arbitrary AST_Node",
|
||||
terminal: "[boolean] whether the chain has ended",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return !this.optional == !node.optional
|
||||
&& prop_equals(this.property, node.property)
|
||||
&& this.expression.equals(node.expression);
|
||||
},
|
||||
get_property: function() {
|
||||
var p = this.property;
|
||||
if (p instanceof AST_Constant) return p.value;
|
||||
@@ -1434,8 +1566,11 @@ var AST_PropAccess = DEFNODE("PropAccess", "expression optional property termina
|
||||
},
|
||||
});
|
||||
|
||||
var AST_Dot = DEFNODE("Dot", null, {
|
||||
var AST_Dot = DEFNODE("Dot", "quoted", {
|
||||
$documentation: "A dotted property access expression",
|
||||
$propdoc: {
|
||||
quoted: "[boolean] whether property is transformed from a quoted string",
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1466,6 +1601,9 @@ var AST_Spread = DEFNODE("Spread", "expression", {
|
||||
$propdoc: {
|
||||
expression: "[AST_Node] expression to be expanded",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.expression.equals(node.expression);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1481,7 +1619,11 @@ var AST_Unary = DEFNODE("Unary", "operator expression", {
|
||||
$documentation: "Base class for unary expressions",
|
||||
$propdoc: {
|
||||
operator: "[string] the operator",
|
||||
expression: "[AST_Node] expression that this unary operator applies to"
|
||||
expression: "[AST_Node] expression that this unary operator applies to",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.operator == node.operator
|
||||
&& this.expression.equals(node.expression);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
@@ -1511,6 +1653,11 @@ var AST_Binary = DEFNODE("Binary", "operator left right", {
|
||||
operator: "[string] the operator",
|
||||
right: "[AST_Node] right-hand side expression"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.operator == node.operator
|
||||
&& this.left.equals(node.left)
|
||||
&& this.right.equals(node.right);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1532,6 +1679,11 @@ var AST_Conditional = DEFNODE("Conditional", "condition consequent alternative",
|
||||
consequent: "[AST_Node]",
|
||||
alternative: "[AST_Node]"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.condition.equals(node.condition)
|
||||
&& this.consequent.equals(node.consequent)
|
||||
&& this.alternative.equals(node.alternative);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1573,6 +1725,9 @@ var AST_Await = DEFNODE("Await", "expression", {
|
||||
$propdoc: {
|
||||
expression: "[AST_Node] expression with Promise to resolve on",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.expression.equals(node.expression);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1590,6 +1745,10 @@ var AST_Yield = DEFNODE("Yield", "expression nested", {
|
||||
expression: "[AST_Node?] return value for iterator, or null if undefined",
|
||||
nested: "[boolean] whether to iterate over expression as generator",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return !this.nested == !node.nested
|
||||
&& prop_equals(this.expression, node.expression);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1612,6 +1771,9 @@ var AST_Array = DEFNODE("Array", "elements", {
|
||||
$propdoc: {
|
||||
elements: "[AST_Node*] array of elements"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return all_equals(this.elements, node.elements);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1654,6 +1816,10 @@ var AST_DestructuredArray = DEFNODE("DestructuredArray", "elements", {
|
||||
$propdoc: {
|
||||
elements: "[(AST_DefaultValue|AST_Destructured|AST_SymbolDeclaration|AST_SymbolRef)*] array of elements",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.rest, node.rest)
|
||||
&& all_equals(this.elements, node.elements);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1671,6 +1837,10 @@ var AST_DestructuredKeyVal = DEFNODE("DestructuredKeyVal", "key value", {
|
||||
key: "[string|AST_Node] property name. For computed property this is an AST_Node.",
|
||||
value: "[AST_DefaultValue|AST_Destructured|AST_SymbolDeclaration|AST_SymbolRef] property value",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.key, node.key)
|
||||
&& this.value.equals(node.value);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1692,6 +1862,10 @@ var AST_DestructuredObject = DEFNODE("DestructuredObject", "properties", {
|
||||
$propdoc: {
|
||||
properties: "[AST_DestructuredKeyVal*] array of properties",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.rest, node.rest)
|
||||
&& all_equals(this.properties, node.properties);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1713,6 +1887,9 @@ var AST_Object = DEFNODE("Object", "properties", {
|
||||
$propdoc: {
|
||||
properties: "[(AST_ObjectProperty|AST_Spread)*] array of properties"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return all_equals(this.properties, node.properties);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1736,6 +1913,10 @@ var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", {
|
||||
key: "[string|AST_Node] property name. For computed property this is an AST_Node.",
|
||||
value: "[AST_Node] property value. For getters and setters this is an AST_Accessor.",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.key, node.key)
|
||||
&& this.value.equals(node.value);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1790,6 +1971,9 @@ var AST_Symbol = DEFNODE("Symbol", "scope name thedef", {
|
||||
scope: "[AST_Scope/S] the current scope (not necessarily the definition scope)",
|
||||
thedef: "[SymbolDef/S] the definition of this symbol"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.thedef ? this.thedef === node.thedef : this.name == node.name;
|
||||
},
|
||||
_validate: function() {
|
||||
if (this.TYPE == "Symbol") throw new Error("should not instantiate AST_Symbol");
|
||||
if (typeof this.name != "string") throw new Error("name must be string");
|
||||
@@ -1807,10 +1991,14 @@ var AST_SymbolConst = DEFNODE("SymbolConst", null, {
|
||||
var AST_SymbolImport = DEFNODE("SymbolImport", "key", {
|
||||
$documentation: "Symbol defined by an `import` statement",
|
||||
$propdoc: {
|
||||
key: "[string] the original `export` name",
|
||||
key: "[AST_String] the original `export` name",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.name == node.name
|
||||
&& this.key.equals(node.key);
|
||||
},
|
||||
_validate: function() {
|
||||
if (typeof this.key != "string") throw new Error("key must be string");
|
||||
if (!(this.key instanceof AST_String)) throw new Error("key must be AST_String");
|
||||
},
|
||||
}, AST_SymbolConst);
|
||||
|
||||
@@ -1864,10 +2052,14 @@ var AST_SymbolRef = DEFNODE("SymbolRef", "fixed in_arg redef", {
|
||||
var AST_SymbolExport = DEFNODE("SymbolExport", "alias", {
|
||||
$documentation: "Reference in an `export` statement",
|
||||
$propdoc: {
|
||||
alias: "[string] the `export` alias",
|
||||
alias: "[AST_String] the `export` alias",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.name == node.name
|
||||
&& this.alias.equals(node.alias);
|
||||
},
|
||||
_validate: function() {
|
||||
if (typeof this.alias != "string") throw new Error("alias must be string");
|
||||
if (!(this.alias instanceof AST_String)) throw new Error("alias must be AST_String");
|
||||
},
|
||||
}, AST_SymbolRef);
|
||||
|
||||
@@ -1877,6 +2069,7 @@ var AST_LabelRef = DEFNODE("LabelRef", null, {
|
||||
|
||||
var AST_ObjectIdentity = DEFNODE("ObjectIdentity", null, {
|
||||
$documentation: "Base class for `super` & `this`",
|
||||
_equals: return_true,
|
||||
_validate: function() {
|
||||
if (this.TYPE == "ObjectIdentity") throw new Error("should not instantiate AST_ObjectIdentity");
|
||||
},
|
||||
@@ -1911,7 +2104,12 @@ var AST_Template = DEFNODE("Template", "expressions strings tag", {
|
||||
$propdoc: {
|
||||
expressions: "[AST_Node*] the placeholder expressions",
|
||||
strings: "[string*] the raw text segments",
|
||||
tag: "[AST_Node] tag function, or null if absent",
|
||||
tag: "[AST_Node?] tag function, or null if absent",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.tag, node.tag)
|
||||
&& list_equals(this.strings, node.strings)
|
||||
&& all_equals(this.expressions, node.expressions);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
@@ -1936,6 +2134,9 @@ var AST_Template = DEFNODE("Template", "expressions strings tag", {
|
||||
|
||||
var AST_Constant = DEFNODE("Constant", null, {
|
||||
$documentation: "Base class for all constants",
|
||||
_equals: function(node) {
|
||||
return this.value === node.value;
|
||||
},
|
||||
_validate: function() {
|
||||
if (this.TYPE == "Constant") throw new Error("should not instantiate AST_Constant");
|
||||
},
|
||||
@@ -1984,6 +2185,9 @@ var AST_RegExp = DEFNODE("RegExp", "value", {
|
||||
$propdoc: {
|
||||
value: "[RegExp] the actual regexp"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return "" + this.value == "" + node.value;
|
||||
},
|
||||
_validate: function() {
|
||||
if (!(this.value instanceof RegExp)) throw new Error("value must be RegExp");
|
||||
},
|
||||
@@ -1991,6 +2195,7 @@ var AST_RegExp = DEFNODE("RegExp", "value", {
|
||||
|
||||
var AST_Atom = DEFNODE("Atom", null, {
|
||||
$documentation: "Base class for atoms",
|
||||
_equals: return_true,
|
||||
_validate: function() {
|
||||
if (this.TYPE == "Atom") throw new Error("should not instantiate AST_Atom");
|
||||
},
|
||||
|
||||
2868
lib/compress.js
2868
lib/compress.js
File diff suppressed because it is too large
Load Diff
@@ -76,19 +76,20 @@ function minify(files, options) {
|
||||
annotations: undefined,
|
||||
compress: {},
|
||||
enclose: false,
|
||||
expression: false,
|
||||
ie: false,
|
||||
ie8: false,
|
||||
keep_fargs: false,
|
||||
keep_fnames: false,
|
||||
mangle: {},
|
||||
module: false,
|
||||
module: undefined,
|
||||
nameCache: null,
|
||||
output: {},
|
||||
parse: {},
|
||||
rename: undefined,
|
||||
sourceMap: false,
|
||||
timings: false,
|
||||
toplevel: !!(options && options["module"]),
|
||||
toplevel: options && !options["expression"] && options["module"] ? true : undefined,
|
||||
v8: false,
|
||||
validate: false,
|
||||
warnings: false,
|
||||
@@ -98,12 +99,14 @@ function minify(files, options) {
|
||||
if (options.validate) AST_Node.enable_validation();
|
||||
var timings = options.timings && { start: Date.now() };
|
||||
if (options.annotations !== undefined) set_shorthand("annotations", options, [ "compress", "output" ]);
|
||||
if (options.expression) set_shorthand("expression", options, [ "compress", "parse" ]);
|
||||
if (options.ie8) options.ie = options.ie || options.ie8;
|
||||
if (options.ie) set_shorthand("ie", options, [ "compress", "mangle", "output", "rename" ]);
|
||||
if (options.keep_fargs) set_shorthand("keep_fargs", options, [ "compress", "mangle", "rename" ]);
|
||||
if (options.keep_fnames) set_shorthand("keep_fnames", options, [ "compress", "mangle", "rename" ]);
|
||||
if (options.module === undefined && !options.ie) options.module = true;
|
||||
if (options.module) set_shorthand("module", options, [ "compress", "parse" ]);
|
||||
if (options.toplevel) set_shorthand("toplevel", options, [ "compress", "mangle", "rename" ]);
|
||||
if (options.toplevel !== undefined) set_shorthand("toplevel", options, [ "compress", "mangle", "rename" ]);
|
||||
if (options.v8) set_shorthand("v8", options, [ "mangle", "output", "rename" ]);
|
||||
if (options.webkit) set_shorthand("webkit", options, [ "compress", "mangle", "output", "rename" ]);
|
||||
var quoted_props;
|
||||
@@ -153,13 +156,11 @@ function minify(files, options) {
|
||||
}, options.warnings == "verbose");
|
||||
if (timings) timings.parse = Date.now();
|
||||
var toplevel;
|
||||
if (files instanceof AST_Toplevel) {
|
||||
options.parse = options.parse || {};
|
||||
if (files instanceof AST_Node) {
|
||||
toplevel = files;
|
||||
} else {
|
||||
if (typeof files == "string") {
|
||||
files = [ files ];
|
||||
}
|
||||
options.parse = options.parse || {};
|
||||
if (typeof files == "string") files = [ files ];
|
||||
options.parse.toplevel = null;
|
||||
var source_map_content = options.sourceMap && options.sourceMap.content;
|
||||
if (typeof source_map_content == "string" && source_map_content != "inline") {
|
||||
@@ -171,17 +172,14 @@ function minify(files, options) {
|
||||
options.parse.toplevel = toplevel = parse(files[name], options.parse);
|
||||
if (source_map_content == "inline") {
|
||||
var inlined_content = read_source_map(name, toplevel);
|
||||
if (inlined_content) {
|
||||
options.sourceMap.orig[name] = parse_source_map(inlined_content);
|
||||
}
|
||||
if (inlined_content) options.sourceMap.orig[name] = parse_source_map(inlined_content);
|
||||
} else if (source_map_content) {
|
||||
options.sourceMap.orig[name] = source_map_content;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (quoted_props) {
|
||||
reserve_quoted_keys(toplevel, quoted_props);
|
||||
}
|
||||
if (options.parse.expression) toplevel = toplevel.wrap_expression();
|
||||
if (quoted_props) reserve_quoted_keys(toplevel, quoted_props);
|
||||
[ "enclose", "wrap" ].forEach(function(action) {
|
||||
var option = options[action];
|
||||
if (!option) return;
|
||||
@@ -208,7 +206,9 @@ function minify(files, options) {
|
||||
toplevel.mangle_names(options.mangle);
|
||||
}
|
||||
if (timings) timings.properties = Date.now();
|
||||
if (quoted_props) reserve_quoted_keys(toplevel, quoted_props);
|
||||
if (options.mangle && options.mangle.properties) mangle_properties(toplevel, options.mangle.properties);
|
||||
if (options.parse.expression) toplevel = toplevel.unwrap_expression();
|
||||
if (timings) timings.output = Date.now();
|
||||
var result = {};
|
||||
var output = defaults(options.output, {
|
||||
|
||||
@@ -125,6 +125,16 @@
|
||||
body: normalize_directives(from_moz(M.body).body),
|
||||
});
|
||||
},
|
||||
CallExpression: function(M) {
|
||||
return new AST_Call({
|
||||
start: my_start_token(M),
|
||||
end: my_end_token(M),
|
||||
expression: from_moz(M.callee),
|
||||
args: M.arguments.map(from_moz),
|
||||
optional: M.optional,
|
||||
pure: M.pure,
|
||||
});
|
||||
},
|
||||
ClassDeclaration: function(M) {
|
||||
return new AST_DefClass({
|
||||
start: my_start_token(M),
|
||||
@@ -192,6 +202,19 @@
|
||||
value: from_moz(M.value),
|
||||
});
|
||||
},
|
||||
StaticBlock: function(M) {
|
||||
var start = my_start_token(M);
|
||||
var end = my_end_token(M);
|
||||
return new AST_ClassInit({
|
||||
start: start,
|
||||
end: end,
|
||||
value: new AST_ClassInitBlock({
|
||||
start: start,
|
||||
end: end,
|
||||
body: normalize_directives(M.body.map(from_moz)),
|
||||
}),
|
||||
});
|
||||
},
|
||||
ForOfStatement: function(M) {
|
||||
return new (M.await ? AST_ForAwaitOf : AST_ForOf)({
|
||||
start: my_start_token(M),
|
||||
@@ -303,13 +326,22 @@
|
||||
});
|
||||
},
|
||||
ExportAllDeclaration: function(M) {
|
||||
var alias = M.exported ? read_name(M.exported) : "*";
|
||||
var start = my_start_token(M);
|
||||
var end = my_end_token(M);
|
||||
return new AST_ExportForeign({
|
||||
start: my_start_token(M),
|
||||
end: my_end_token(M),
|
||||
aliases: [ alias ],
|
||||
keys: [ "*" ],
|
||||
path: M.source.value,
|
||||
start: start,
|
||||
end: end,
|
||||
aliases: [ M.exported ? from_moz_alias(M.exported) : new AST_String({
|
||||
start: start,
|
||||
value: "*",
|
||||
end: end,
|
||||
}) ],
|
||||
keys: [ new AST_String({
|
||||
start: start,
|
||||
value: "*",
|
||||
end: end,
|
||||
}) ],
|
||||
path: from_moz(M.source),
|
||||
});
|
||||
},
|
||||
ExportDefaultDeclaration: function(M) {
|
||||
@@ -346,15 +378,15 @@
|
||||
if (M.source) {
|
||||
var aliases = [], keys = [];
|
||||
M.specifiers.forEach(function(prop) {
|
||||
aliases.push(read_name(prop.exported));
|
||||
keys.push(read_name(prop.local));
|
||||
aliases.push(from_moz_alias(prop.exported));
|
||||
keys.push(from_moz_alias(prop.local));
|
||||
});
|
||||
return new AST_ExportForeign({
|
||||
start: my_start_token(M),
|
||||
end: my_end_token(M),
|
||||
aliases: aliases,
|
||||
keys: keys,
|
||||
path: M.source.value,
|
||||
path: from_moz(M.source),
|
||||
});
|
||||
}
|
||||
return new AST_ExportReferences({
|
||||
@@ -362,38 +394,48 @@
|
||||
end: my_end_token(M),
|
||||
properties: M.specifiers.map(function(prop) {
|
||||
var sym = new AST_SymbolExport(from_moz(prop.local));
|
||||
sym.alias = read_name(prop.exported);
|
||||
sym.alias = from_moz_alias(prop.exported);
|
||||
return sym;
|
||||
}),
|
||||
});
|
||||
},
|
||||
ImportDeclaration: function(M) {
|
||||
var start = my_start_token(M);
|
||||
var end = my_end_token(M);
|
||||
var all = null, def = null, props = null;
|
||||
M.specifiers.forEach(function(prop) {
|
||||
var sym = new AST_SymbolImport(from_moz(prop.local));
|
||||
switch (prop.type) {
|
||||
case "ImportDefaultSpecifier":
|
||||
def = sym;
|
||||
def.key = "";
|
||||
def.key = new AST_String({
|
||||
start: start,
|
||||
value: "",
|
||||
end: end,
|
||||
});
|
||||
break;
|
||||
case "ImportNamespaceSpecifier":
|
||||
all = sym;
|
||||
all.key = "*";
|
||||
all.key = new AST_String({
|
||||
start: start,
|
||||
value: "*",
|
||||
end: end,
|
||||
});
|
||||
break;
|
||||
default:
|
||||
sym.key = prop.imported.name || syn.name;
|
||||
sym.key = from_moz_alias(prop.imported);
|
||||
if (!props) props = [];
|
||||
props.push(sym);
|
||||
break;
|
||||
}
|
||||
});
|
||||
return new AST_Import({
|
||||
start: my_start_token(M),
|
||||
end: my_end_token(M),
|
||||
start: start,
|
||||
end: end,
|
||||
all: all,
|
||||
default: def,
|
||||
properties: props,
|
||||
path: M.source.value,
|
||||
path: from_moz(M.source),
|
||||
});
|
||||
},
|
||||
ImportExpression: function(M) {
|
||||
@@ -426,7 +468,7 @@
|
||||
end: my_end_token(M),
|
||||
};
|
||||
if (M.bigint) {
|
||||
args.value = M.bigint.toLowerCase() + "n";
|
||||
args.value = M.bigint.toLowerCase();
|
||||
return new AST_BigInt(args);
|
||||
}
|
||||
var val = M.value;
|
||||
@@ -599,7 +641,6 @@
|
||||
map("AssignmentPattern", AST_DefaultValue, "left>name, right>value");
|
||||
map("ConditionalExpression", AST_Conditional, "test>condition, consequent>consequent, alternate>alternative");
|
||||
map("NewExpression", AST_New, "callee>expression, arguments@args, pure=pure");
|
||||
map("CallExpression", AST_Call, "callee>expression, arguments@args, optional=optional, pure=pure");
|
||||
map("SequenceExpression", AST_Sequence, "expressions@expressions");
|
||||
map("SpreadElement", AST_Spread, "argument>expression");
|
||||
map("ObjectExpression", AST_Object, "properties@properties");
|
||||
@@ -636,6 +677,7 @@
|
||||
type: "ArrowFunctionExpression",
|
||||
async: is_async(M),
|
||||
params: params,
|
||||
expression: !!M.value,
|
||||
body: M.value ? to_moz(M.value) : to_moz_scope("BlockStatement", M),
|
||||
};
|
||||
return {
|
||||
@@ -648,6 +690,21 @@
|
||||
};
|
||||
});
|
||||
|
||||
def_to_moz(AST_Call, function To_Moz_CallExpression(M) {
|
||||
var expr = M.expression;
|
||||
if (M.args.length == 1 && expr instanceof AST_SymbolRef && expr.name == "import") return {
|
||||
type: "ImportExpression",
|
||||
source: to_moz(M.args[0]),
|
||||
};
|
||||
return {
|
||||
type: "CallExpression",
|
||||
callee: to_moz(expr),
|
||||
arguments: M.args.map(to_moz),
|
||||
optional: M.optional,
|
||||
pure: M.pure,
|
||||
};
|
||||
});
|
||||
|
||||
def_to_moz(AST_DefClass, function To_Moz_ClassDeclaration(M) {
|
||||
return {
|
||||
type: "ClassDeclaration",
|
||||
@@ -714,6 +771,10 @@
|
||||
};
|
||||
});
|
||||
|
||||
def_to_moz(AST_ClassInit, function To_Moz_StaticBlock(M) {
|
||||
return to_moz_scope("StaticBlock", M.value);
|
||||
});
|
||||
|
||||
function To_Moz_ForOfStatement(is_await) {
|
||||
return function(M) {
|
||||
return {
|
||||
@@ -731,6 +792,7 @@
|
||||
def_to_moz(AST_Directive, function To_Moz_Directive(M) {
|
||||
return {
|
||||
type: "ExpressionStatement",
|
||||
directive: M.value,
|
||||
expression: set_moz_loc(M, {
|
||||
type: "Literal",
|
||||
value: M.value,
|
||||
@@ -751,7 +813,6 @@
|
||||
type: "TryStatement",
|
||||
block: to_moz_block(M),
|
||||
handler: to_moz(M.bcatch),
|
||||
guardedHandlers: [],
|
||||
finalizer: to_moz(M.bfinally),
|
||||
};
|
||||
});
|
||||
@@ -760,7 +821,6 @@
|
||||
return {
|
||||
type: "CatchClause",
|
||||
param: to_moz(M.argname),
|
||||
guard: null,
|
||||
body: to_moz_block(M),
|
||||
};
|
||||
});
|
||||
@@ -769,6 +829,7 @@
|
||||
return {
|
||||
type: "ExportNamedDeclaration",
|
||||
declaration: to_moz(M.body),
|
||||
specifiers: [],
|
||||
};
|
||||
});
|
||||
|
||||
@@ -780,38 +841,26 @@
|
||||
});
|
||||
|
||||
def_to_moz(AST_ExportForeign, function To_Moz_ExportAllDeclaration_ExportNamedDeclaration(M) {
|
||||
if (M.keys[0] == "*") return {
|
||||
if (M.keys[0].value == "*") return {
|
||||
type: "ExportAllDeclaration",
|
||||
exported: M.aliases[0] == "*" ? null : {
|
||||
type: "Identifier",
|
||||
name: M.aliases[0],
|
||||
},
|
||||
source: {
|
||||
type: "Literal",
|
||||
value: M.path,
|
||||
},
|
||||
exported: M.aliases[0].value == "*" ? null : to_moz_alias(M.aliases[0]),
|
||||
source: to_moz(M.path),
|
||||
};
|
||||
var specifiers = [];
|
||||
for (var i = 0; i < M.aliases.length; i++) {
|
||||
specifiers.push({
|
||||
specifiers.push(set_moz_loc({
|
||||
start: M.keys[i].start,
|
||||
end: M.aliases[i].end,
|
||||
}, {
|
||||
type: "ExportSpecifier",
|
||||
exported: {
|
||||
type: "Identifier",
|
||||
name: M.aliases[i],
|
||||
},
|
||||
local: {
|
||||
type: "Identifier",
|
||||
name: M.keys[i],
|
||||
},
|
||||
});
|
||||
local: to_moz_alias(M.keys[i]),
|
||||
exported: to_moz_alias(M.aliases[i]),
|
||||
}));
|
||||
}
|
||||
return {
|
||||
type: "ExportNamedDeclaration",
|
||||
specifiers: specifiers,
|
||||
source: {
|
||||
type: "Literal",
|
||||
value: M.path,
|
||||
},
|
||||
source: to_moz(M.path),
|
||||
};
|
||||
});
|
||||
|
||||
@@ -819,44 +868,41 @@
|
||||
return {
|
||||
type: "ExportNamedDeclaration",
|
||||
specifiers: M.properties.map(function(prop) {
|
||||
return {
|
||||
return set_moz_loc({
|
||||
start: prop.start,
|
||||
end: prop.alias.end,
|
||||
}, {
|
||||
type: "ExportSpecifier",
|
||||
local: to_moz(prop),
|
||||
exported: {
|
||||
type: "Identifier",
|
||||
name: prop.alias,
|
||||
},
|
||||
};
|
||||
exported: to_moz_alias(prop.alias),
|
||||
});
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
def_to_moz(AST_Import, function To_Moz_ImportDeclaration(M) {
|
||||
var specifiers = M.properties ? M.properties.map(function(prop) {
|
||||
return {
|
||||
return set_moz_loc({
|
||||
start: prop.key.start,
|
||||
end: prop.end,
|
||||
}, {
|
||||
type: "ImportSpecifier",
|
||||
local: to_moz(prop),
|
||||
imported: {
|
||||
type: "Identifier",
|
||||
name: prop.key,
|
||||
},
|
||||
};
|
||||
imported: to_moz_alias(prop.key),
|
||||
});
|
||||
}) : [];
|
||||
if (M.all) specifiers.unshift({
|
||||
if (M.all) specifiers.unshift(set_moz_loc(M.all, {
|
||||
type: "ImportNamespaceSpecifier",
|
||||
local: to_moz(M.all),
|
||||
});
|
||||
if (M.default) specifiers.unshift({
|
||||
}));
|
||||
if (M.default) specifiers.unshift(set_moz_loc(M.default, {
|
||||
type: "ImportDefaultSpecifier",
|
||||
local: to_moz(M.default),
|
||||
});
|
||||
}));
|
||||
return {
|
||||
type: "ImportDeclaration",
|
||||
specifiers: specifiers,
|
||||
source: {
|
||||
type: "Literal",
|
||||
value: M.path,
|
||||
},
|
||||
source: to_moz(M.path),
|
||||
};
|
||||
});
|
||||
|
||||
@@ -933,6 +979,8 @@
|
||||
type: "Property",
|
||||
kind: "init",
|
||||
computed: computed,
|
||||
method: false,
|
||||
shorthand: false,
|
||||
key: key,
|
||||
value: to_moz(M.value),
|
||||
};
|
||||
@@ -969,6 +1017,7 @@
|
||||
kind: kind,
|
||||
computed: computed,
|
||||
method: M instanceof AST_ObjectMethod,
|
||||
shorthand: false,
|
||||
key: key,
|
||||
value: to_moz(M.value),
|
||||
};
|
||||
@@ -1022,8 +1071,8 @@
|
||||
var value = M.value;
|
||||
return {
|
||||
type: "Literal",
|
||||
bigint: value.slice(0, -1),
|
||||
raw: value,
|
||||
bigint: value,
|
||||
raw: value + "n",
|
||||
};
|
||||
});
|
||||
|
||||
@@ -1203,6 +1252,14 @@
|
||||
return node;
|
||||
}
|
||||
|
||||
function from_moz_alias(moz) {
|
||||
return new AST_String({
|
||||
start: my_start_token(moz),
|
||||
value: read_name(moz),
|
||||
end: my_end_token(moz),
|
||||
});
|
||||
}
|
||||
|
||||
AST_Node.from_mozilla_ast = function(node) {
|
||||
var save_stack = FROM_MOZ_STACK;
|
||||
FROM_MOZ_STACK = [];
|
||||
@@ -1254,6 +1311,13 @@
|
||||
return node != null ? node.to_mozilla_ast() : null;
|
||||
}
|
||||
|
||||
function to_moz_alias(alias) {
|
||||
return is_identifier_string(alias.value) ? set_moz_loc(alias, {
|
||||
type: "Identifier",
|
||||
name: alias.value,
|
||||
}) : to_moz(alias);
|
||||
}
|
||||
|
||||
function to_moz_block(node) {
|
||||
return {
|
||||
type: "BlockStatement",
|
||||
|
||||
110
lib/output.js
110
lib/output.js
@@ -55,6 +55,7 @@ function OutputStream(options) {
|
||||
beautify : false,
|
||||
braces : false,
|
||||
comments : false,
|
||||
extendscript : false,
|
||||
galio : false,
|
||||
ie : false,
|
||||
indent_level : 4,
|
||||
@@ -75,7 +76,7 @@ function OutputStream(options) {
|
||||
wrap_iife : false,
|
||||
}, true);
|
||||
|
||||
// Convert comment option to RegExp if neccessary and set up comments filter
|
||||
// Convert comment option to RegExp if necessary and set up comments filter
|
||||
var comment_filter = return_false; // Default case, throw all comments away
|
||||
if (options.comments) {
|
||||
var comments = options.comments;
|
||||
@@ -406,10 +407,11 @@ function OutputStream(options) {
|
||||
print(";");
|
||||
}
|
||||
|
||||
function with_block(cont) {
|
||||
function with_block(cont, end) {
|
||||
print("{");
|
||||
newline();
|
||||
with_indent(cont);
|
||||
add_mapping(end);
|
||||
indent();
|
||||
print("}");
|
||||
}
|
||||
@@ -699,6 +701,7 @@ function OutputStream(options) {
|
||||
if (p instanceof AST_Class) return true;
|
||||
// (x++)[y]
|
||||
// (typeof x).y
|
||||
// https://github.com/mishoo/UglifyJS/issues/115
|
||||
if (p instanceof AST_PropAccess) return p.expression === this;
|
||||
// (~x)`foo`
|
||||
if (p instanceof AST_Template) return p.tag === this;
|
||||
@@ -874,7 +877,9 @@ function OutputStream(options) {
|
||||
return needs_parens_assign_cond(this, output);
|
||||
});
|
||||
PARENS(AST_Conditional, function(output) {
|
||||
return needs_parens_assign_cond(this, output);
|
||||
return needs_parens_assign_cond(this, output)
|
||||
// https://github.com/mishoo/UglifyJS/issues/1144
|
||||
|| output.option("extendscript") && output.parent() instanceof AST_Conditional;
|
||||
});
|
||||
PARENS(AST_Yield, function(output) {
|
||||
return needs_parens_assign_cond(this, output);
|
||||
@@ -953,7 +958,7 @@ function OutputStream(options) {
|
||||
if (self.body.length > 0) {
|
||||
output.with_block(function() {
|
||||
display_body(self.body, false, output, allow_directives);
|
||||
});
|
||||
}, self.end);
|
||||
} else print_braced_empty(self, output);
|
||||
}
|
||||
DEFPRINT(AST_BlockStatement, function(output) {
|
||||
@@ -992,7 +997,7 @@ function OutputStream(options) {
|
||||
if (self.init instanceof AST_Definitions) {
|
||||
self.init.print(output);
|
||||
} else {
|
||||
parenthesize_for_noin(self.init, output, true);
|
||||
parenthesize_for_no_in(self.init, output, true);
|
||||
}
|
||||
output.print(";");
|
||||
output.space();
|
||||
@@ -1061,6 +1066,14 @@ function OutputStream(options) {
|
||||
}
|
||||
output.semicolon();
|
||||
});
|
||||
function print_alias(alias, output) {
|
||||
var value = alias.value;
|
||||
if (value == "*" || is_identifier_string(value)) {
|
||||
output.print_name(value);
|
||||
} else {
|
||||
output.print_string(value, alias.quote);
|
||||
}
|
||||
}
|
||||
DEFPRINT(AST_ExportForeign, function(output) {
|
||||
var self = this;
|
||||
output.print("export");
|
||||
@@ -1068,7 +1081,7 @@ function OutputStream(options) {
|
||||
var len = self.keys.length;
|
||||
if (len == 0) {
|
||||
print_braced_empty(self, output);
|
||||
} else if (self.keys[0] == "*") {
|
||||
} else if (self.keys[0].value == "*") {
|
||||
print_entry(0);
|
||||
} else output.with_block(function() {
|
||||
output.indent();
|
||||
@@ -1080,22 +1093,22 @@ function OutputStream(options) {
|
||||
print_entry(i);
|
||||
}
|
||||
output.newline();
|
||||
});
|
||||
}, self.end);
|
||||
output.space();
|
||||
output.print("from");
|
||||
output.space();
|
||||
output.print_string(self.path, self.quote);
|
||||
self.path.print(output);
|
||||
output.semicolon();
|
||||
|
||||
function print_entry(index) {
|
||||
var alias = self.aliases[index];
|
||||
var key = self.keys[index];
|
||||
output.print_name(key);
|
||||
if (alias != key) {
|
||||
print_alias(key, output);
|
||||
if (alias.value != key.value) {
|
||||
output.space();
|
||||
output.print("as");
|
||||
output.space();
|
||||
output.print_name(alias);
|
||||
print_alias(alias, output);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1124,7 +1137,7 @@ function OutputStream(options) {
|
||||
output.print("from");
|
||||
output.space();
|
||||
}
|
||||
output.print_string(self.path, self.quote);
|
||||
self.path.print(output);
|
||||
output.semicolon();
|
||||
});
|
||||
|
||||
@@ -1344,7 +1357,7 @@ function OutputStream(options) {
|
||||
if (i < last && branch.body.length > 0)
|
||||
output.newline();
|
||||
});
|
||||
});
|
||||
}, self.end);
|
||||
});
|
||||
function print_branch_body(self, output) {
|
||||
output.newline();
|
||||
@@ -1400,7 +1413,7 @@ function OutputStream(options) {
|
||||
print_braced(this, output);
|
||||
});
|
||||
|
||||
function print_definitinos(type) {
|
||||
function print_definitions(type) {
|
||||
return function(output) {
|
||||
var self = this;
|
||||
output.print(type);
|
||||
@@ -1413,15 +1426,15 @@ function OutputStream(options) {
|
||||
if (!(p instanceof AST_IterationStatement && p.init === self)) output.semicolon();
|
||||
};
|
||||
}
|
||||
DEFPRINT(AST_Const, print_definitinos("const"));
|
||||
DEFPRINT(AST_Let, print_definitinos("let"));
|
||||
DEFPRINT(AST_Var, print_definitinos("var"));
|
||||
DEFPRINT(AST_Const, print_definitions("const"));
|
||||
DEFPRINT(AST_Let, print_definitions("let"));
|
||||
DEFPRINT(AST_Var, print_definitions("var"));
|
||||
|
||||
function parenthesize_for_noin(node, output, noin) {
|
||||
function parenthesize_for_no_in(node, output, no_in) {
|
||||
var parens = false;
|
||||
// need to take some precautions here:
|
||||
// https://github.com/mishoo/UglifyJS/issues/60
|
||||
if (noin) node.walk(new TreeWalker(function(node) {
|
||||
if (no_in) node.walk(new TreeWalker(function(node) {
|
||||
if (parens) return true;
|
||||
if (node instanceof AST_Binary && node.operator == "in") return parens = true;
|
||||
if (node instanceof AST_Scope && !(is_arrow(node) && node.value)) return true;
|
||||
@@ -1437,8 +1450,8 @@ function OutputStream(options) {
|
||||
output.print("=");
|
||||
output.space();
|
||||
var p = output.parent(1);
|
||||
var noin = p instanceof AST_For || p instanceof AST_ForEnumeration;
|
||||
parenthesize_for_noin(self.value, output, noin);
|
||||
var no_in = p instanceof AST_For || p instanceof AST_ForEnumeration;
|
||||
parenthesize_for_no_in(self.value, output, no_in);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1464,14 +1477,12 @@ function OutputStream(options) {
|
||||
output.print("/*@__PURE__*/");
|
||||
}
|
||||
function print_call_args(self, output) {
|
||||
if (self.expression instanceof AST_Call || self.expression instanceof AST_Lambda) {
|
||||
output.add_mapping(self.start);
|
||||
}
|
||||
output.with_parens(function() {
|
||||
self.args.forEach(function(expr, i) {
|
||||
if (i) output.comma();
|
||||
expr.print(output);
|
||||
});
|
||||
output.add_mapping(self.end);
|
||||
});
|
||||
}
|
||||
DEFPRINT(AST_Call, function(output) {
|
||||
@@ -1506,11 +1517,12 @@ function OutputStream(options) {
|
||||
var expr = self.expression;
|
||||
expr.print(output);
|
||||
var prop = self.property;
|
||||
if (output.option("ie") && RESERVED_WORDS[prop]) {
|
||||
output.print(self.optional ? "?.[" : "[");
|
||||
output.add_mapping(self.end);
|
||||
output.print_string(prop);
|
||||
output.print("]");
|
||||
if (output.option("ie") && RESERVED_WORDS[prop] || self.quoted && output.option("keep_quoted_props")) {
|
||||
if (self.optional) output.print("?.");
|
||||
output.with_square(function() {
|
||||
output.add_mapping(self.end);
|
||||
output.print_string(prop);
|
||||
});
|
||||
} else {
|
||||
if (expr instanceof AST_Number && !/[ex.)]/i.test(output.last())) output.print(".");
|
||||
output.print(self.optional ? "?." : ".");
|
||||
@@ -1522,9 +1534,10 @@ function OutputStream(options) {
|
||||
DEFPRINT(AST_Sub, function(output) {
|
||||
var self = this;
|
||||
self.expression.print(output);
|
||||
output.print(self.optional ? "?.[" : "[");
|
||||
self.property.print(output);
|
||||
output.print("]");
|
||||
if (self.optional) output.print("?.");
|
||||
output.with_square(function() {
|
||||
self.property.print(output);
|
||||
});
|
||||
});
|
||||
DEFPRINT(AST_Spread, function(output) {
|
||||
output.print("...");
|
||||
@@ -1543,8 +1556,10 @@ function OutputStream(options) {
|
||||
exp.print(output);
|
||||
});
|
||||
DEFPRINT(AST_UnaryPostfix, function(output) {
|
||||
this.expression.print(output);
|
||||
output.print(this.operator);
|
||||
var self = this;
|
||||
self.expression.print(output);
|
||||
output.add_mapping(self.end);
|
||||
output.print(self.operator);
|
||||
});
|
||||
DEFPRINT(AST_Binary, function(output) {
|
||||
var self = this;
|
||||
@@ -1637,7 +1652,8 @@ function OutputStream(options) {
|
||||
value.print(output);
|
||||
});
|
||||
DEFPRINT(AST_DestructuredObject, function(output) {
|
||||
var props = this.properties, len = props.length, rest = this.rest;
|
||||
var self = this;
|
||||
var props = self.properties, len = props.length, rest = self.rest;
|
||||
if (len || rest) output.with_block(function() {
|
||||
props.forEach(function(prop, i) {
|
||||
if (i) {
|
||||
@@ -1657,8 +1673,8 @@ function OutputStream(options) {
|
||||
rest.print(output);
|
||||
}
|
||||
output.newline();
|
||||
});
|
||||
else print_braced_empty(this, output);
|
||||
}, self.end);
|
||||
else print_braced_empty(self, output);
|
||||
});
|
||||
function print_properties(self, output, no_comma) {
|
||||
var props = self.properties;
|
||||
@@ -1672,7 +1688,7 @@ function OutputStream(options) {
|
||||
prop.print(output);
|
||||
});
|
||||
output.newline();
|
||||
});
|
||||
}, self.end);
|
||||
else print_braced_empty(self, output);
|
||||
}
|
||||
DEFPRINT(AST_Object, function(output) {
|
||||
@@ -1734,19 +1750,19 @@ function OutputStream(options) {
|
||||
var name = get_symbol_name(self);
|
||||
output.print_name(name);
|
||||
var alias = self.alias;
|
||||
if (alias != name) {
|
||||
if (alias.value != name) {
|
||||
output.space();
|
||||
output.print("as");
|
||||
output.space();
|
||||
output.print_name(alias);
|
||||
print_alias(alias, output);
|
||||
}
|
||||
});
|
||||
DEFPRINT(AST_SymbolImport, function(output) {
|
||||
var self = this;
|
||||
var name = get_symbol_name(self);
|
||||
var key = self.key;
|
||||
if (key && key != name) {
|
||||
output.print_name(key);
|
||||
if (key.value && key.value != name) {
|
||||
print_alias(key, output);
|
||||
output.space();
|
||||
output.print("as");
|
||||
output.space();
|
||||
@@ -1767,6 +1783,9 @@ function OutputStream(options) {
|
||||
output.print(self.strings[i]);
|
||||
output.print("`");
|
||||
});
|
||||
DEFPRINT(AST_BigInt, function(output) {
|
||||
output.print(this.value + "n");
|
||||
});
|
||||
DEFPRINT(AST_Constant, function(output) {
|
||||
output.print("" + this.value);
|
||||
});
|
||||
@@ -1882,7 +1901,7 @@ function OutputStream(options) {
|
||||
output.indent();
|
||||
stmt.print(output);
|
||||
output.newline();
|
||||
});
|
||||
}, stmt.end);
|
||||
}
|
||||
|
||||
/* -----[ source map generators ]----- */
|
||||
@@ -1905,22 +1924,27 @@ function OutputStream(options) {
|
||||
// or if we should add even more.
|
||||
DEFMAP([
|
||||
AST_Array,
|
||||
AST_Await,
|
||||
AST_BlockStatement,
|
||||
AST_Catch,
|
||||
AST_Constant,
|
||||
AST_Debugger,
|
||||
AST_Definitions,
|
||||
AST_Destructured,
|
||||
AST_Directive,
|
||||
AST_Finally,
|
||||
AST_Jump,
|
||||
AST_Lambda,
|
||||
AST_New,
|
||||
AST_Object,
|
||||
AST_Spread,
|
||||
AST_StatementWithBody,
|
||||
AST_Symbol,
|
||||
AST_Switch,
|
||||
AST_SwitchBranch,
|
||||
AST_Try,
|
||||
AST_UnaryPrefix,
|
||||
AST_Yield,
|
||||
], function(output) {
|
||||
output.add_mapping(this.start);
|
||||
});
|
||||
|
||||
177
lib/parse.js
177
lib/parse.js
@@ -207,11 +207,14 @@ function JS_Parse_Error(message, filename, line, col, pos) {
|
||||
this.line = line;
|
||||
this.col = col;
|
||||
this.pos = pos;
|
||||
try {
|
||||
throw new SyntaxError(message, filename, line, col);
|
||||
} catch (cause) {
|
||||
configure_error_stack(this, cause);
|
||||
}
|
||||
}
|
||||
JS_Parse_Error.prototype = Object.create(Error.prototype);
|
||||
JS_Parse_Error.prototype = Object.create(SyntaxError.prototype);
|
||||
JS_Parse_Error.prototype.constructor = JS_Parse_Error;
|
||||
JS_Parse_Error.prototype.name = "SyntaxError";
|
||||
configure_error_stack(JS_Parse_Error);
|
||||
|
||||
function js_error(message, filename, line, col, pos) {
|
||||
throw new JS_Parse_Error(message, filename, line, col, pos);
|
||||
@@ -391,7 +394,8 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
var valid = parse_js_number(num);
|
||||
if (isNaN(valid)) parse_error("Invalid syntax: " + num);
|
||||
if (has_dot || has_e || peek() != "n") return token("num", valid);
|
||||
return token("bigint", num.toLowerCase() + next());
|
||||
next();
|
||||
return token("bigint", num.toLowerCase());
|
||||
}
|
||||
|
||||
function read_escaped_char(in_string) {
|
||||
@@ -552,16 +556,8 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
|
||||
function handle_dot() {
|
||||
next();
|
||||
var ch = peek();
|
||||
if (ch == ".") {
|
||||
var op = ".";
|
||||
do {
|
||||
op += ".";
|
||||
next();
|
||||
} while (peek() == ".");
|
||||
return token("operator", op);
|
||||
}
|
||||
return is_digit(ch.charCodeAt(0)) ? read_num(".") : token("punc", ".");
|
||||
if (looking_at("..")) return token("operator", "." + next() + next());
|
||||
return is_digit(peek().charCodeAt(0)) ? read_num(".") : token("punc", ".");
|
||||
}
|
||||
|
||||
function read_word() {
|
||||
@@ -790,7 +786,7 @@ function parse($TEXT, options) {
|
||||
else if (!optional && !can_insert_semicolon()) expect(";");
|
||||
}
|
||||
|
||||
function parenthesised() {
|
||||
function parenthesized() {
|
||||
expect("(");
|
||||
var exp = expression();
|
||||
expect(")");
|
||||
@@ -815,7 +811,7 @@ function parse($TEXT, options) {
|
||||
}
|
||||
}
|
||||
|
||||
var statement = embed_tokens(function() {
|
||||
var statement = embed_tokens(function(toplevel) {
|
||||
handle_regexp();
|
||||
switch (S.token.type) {
|
||||
case "string":
|
||||
@@ -854,15 +850,15 @@ function parse($TEXT, options) {
|
||||
if (S.in_async) return simple_statement();
|
||||
break;
|
||||
case "export":
|
||||
if (!toplevel && options.module !== "") unexpected();
|
||||
next();
|
||||
return export_();
|
||||
case "import":
|
||||
var token = peek();
|
||||
if (!(token.type == "punc" && /^[(.]$/.test(token.value))) {
|
||||
next();
|
||||
return import_();
|
||||
}
|
||||
break;
|
||||
if (token.type == "punc" && /^[(.]$/.test(token.value)) break;
|
||||
if (!toplevel && options.module !== "") unexpected();
|
||||
next();
|
||||
return import_();
|
||||
case "let":
|
||||
if (is_vardefs()) {
|
||||
next();
|
||||
@@ -928,18 +924,18 @@ function parse($TEXT, options) {
|
||||
next();
|
||||
var body = in_loop(statement);
|
||||
expect_token("keyword", "while");
|
||||
var condition = parenthesised();
|
||||
var condition = parenthesized();
|
||||
semicolon(true);
|
||||
return new AST_Do({
|
||||
body : body,
|
||||
condition : condition
|
||||
condition : condition,
|
||||
});
|
||||
|
||||
case "while":
|
||||
next();
|
||||
return new AST_While({
|
||||
condition : parenthesised(),
|
||||
body : in_loop(statement)
|
||||
condition : parenthesized(),
|
||||
body : in_loop(statement),
|
||||
});
|
||||
|
||||
case "for":
|
||||
@@ -967,15 +963,13 @@ function parse($TEXT, options) {
|
||||
value = expression();
|
||||
semicolon();
|
||||
}
|
||||
return new AST_Return({
|
||||
value: value
|
||||
});
|
||||
return new AST_Return({ value: value });
|
||||
|
||||
case "switch":
|
||||
next();
|
||||
return new AST_Switch({
|
||||
expression : parenthesised(),
|
||||
body : in_loop(switch_body_)
|
||||
expression : parenthesized(),
|
||||
body : in_loop(switch_body_),
|
||||
});
|
||||
|
||||
case "throw":
|
||||
@@ -984,9 +978,7 @@ function parse($TEXT, options) {
|
||||
croak("Illegal newline after 'throw'");
|
||||
var value = expression();
|
||||
semicolon();
|
||||
return new AST_Throw({
|
||||
value: value
|
||||
});
|
||||
return new AST_Throw({ value: value });
|
||||
|
||||
case "try":
|
||||
next();
|
||||
@@ -1004,8 +996,8 @@ function parse($TEXT, options) {
|
||||
}
|
||||
next();
|
||||
return new AST_With({
|
||||
expression : parenthesised(),
|
||||
body : statement()
|
||||
expression : parenthesized(),
|
||||
body : statement(),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1064,13 +1056,13 @@ function parse($TEXT, options) {
|
||||
return stat;
|
||||
}
|
||||
|
||||
function has_modifier(name) {
|
||||
function has_modifier(name, no_nlb) {
|
||||
if (!is("name", name)) return;
|
||||
var token = peek();
|
||||
if (!token) return;
|
||||
if (is_token(token, "operator", "=")) return;
|
||||
if (token.type == "punc" && /^[(;}]$/.test(token.value)) return;
|
||||
if (has_newline_before(token)) return;
|
||||
if (no_nlb && has_newline_before(token)) return;
|
||||
return next();
|
||||
}
|
||||
|
||||
@@ -1100,7 +1092,7 @@ function parse($TEXT, options) {
|
||||
}
|
||||
var start = S.token;
|
||||
var fixed = !!has_modifier("static");
|
||||
var async = has_modifier("async");
|
||||
var async = has_modifier("async", true);
|
||||
if (is("operator", "*")) {
|
||||
next();
|
||||
var internal = is("name") && /^#/.test(S.token.value);
|
||||
@@ -1429,41 +1421,54 @@ function parse($TEXT, options) {
|
||||
};
|
||||
|
||||
function if_() {
|
||||
var cond = parenthesised(), body = statement(), belse = null;
|
||||
var cond = parenthesized(), body = statement(), alt = null;
|
||||
if (is("keyword", "else")) {
|
||||
next();
|
||||
belse = statement();
|
||||
alt = statement();
|
||||
}
|
||||
return new AST_If({
|
||||
condition : cond,
|
||||
body : body,
|
||||
alternative : belse
|
||||
alternative : alt,
|
||||
});
|
||||
}
|
||||
|
||||
function is_alias() {
|
||||
return is("name") || is_identifier_string(S.token.value);
|
||||
return is("name") || is("string") || is_identifier_string(S.token.value);
|
||||
}
|
||||
|
||||
function make_string(token) {
|
||||
return new AST_String({
|
||||
start: token,
|
||||
quote: token.quote,
|
||||
value: token.value,
|
||||
end: token,
|
||||
});
|
||||
}
|
||||
|
||||
function as_path() {
|
||||
var path = S.token;
|
||||
expect_token("string");
|
||||
semicolon();
|
||||
return make_string(path);
|
||||
}
|
||||
|
||||
function export_() {
|
||||
if (is("operator", "*")) {
|
||||
var key = S.token;
|
||||
var alias = key;
|
||||
next();
|
||||
var alias = "*";
|
||||
if (is("name", "as")) {
|
||||
next();
|
||||
if (!is_alias()) expect_token("name");
|
||||
alias = S.token.value;
|
||||
alias = S.token;
|
||||
next();
|
||||
}
|
||||
expect_token("name", "from");
|
||||
var path = S.token;
|
||||
expect_token("string");
|
||||
semicolon();
|
||||
return new AST_ExportForeign({
|
||||
aliases: [ alias ],
|
||||
keys: [ "*" ],
|
||||
path: path.value,
|
||||
quote: path.quote,
|
||||
aliases: [ make_string(alias) ],
|
||||
keys: [ make_string(key) ],
|
||||
path: as_path(),
|
||||
});
|
||||
}
|
||||
if (is("punc", "{")) {
|
||||
@@ -1477,26 +1482,20 @@ function parse($TEXT, options) {
|
||||
if (is("name", "as")) {
|
||||
next();
|
||||
if (!is_alias()) expect_token("name");
|
||||
aliases.push(S.token.value);
|
||||
aliases.push(S.token);
|
||||
next();
|
||||
} else {
|
||||
aliases.push(key.value);
|
||||
aliases.push(key);
|
||||
}
|
||||
if (!is("punc", "}")) expect(",");
|
||||
}
|
||||
expect("}");
|
||||
if (is("name", "from")) {
|
||||
next();
|
||||
var path = S.token;
|
||||
expect_token("string");
|
||||
semicolon();
|
||||
return new AST_ExportForeign({
|
||||
aliases: aliases,
|
||||
keys: keys.map(function(token) {
|
||||
return token.value;
|
||||
}),
|
||||
path: path.value,
|
||||
quote: path.quote,
|
||||
aliases: aliases.map(make_string),
|
||||
keys: keys.map(make_string),
|
||||
path: as_path(),
|
||||
});
|
||||
}
|
||||
semicolon();
|
||||
@@ -1504,7 +1503,7 @@ function parse($TEXT, options) {
|
||||
properties: keys.map(function(token, index) {
|
||||
if (!is_token(token, "name")) token_error(token, "Name expected");
|
||||
var sym = _make_symbol(AST_SymbolExport, token);
|
||||
sym.alias = aliases[index];
|
||||
sym.alias = make_string(aliases[index]);
|
||||
return sym;
|
||||
}),
|
||||
});
|
||||
@@ -1594,26 +1593,42 @@ function parse($TEXT, options) {
|
||||
var all = null;
|
||||
var def = as_symbol(AST_SymbolImport, true);
|
||||
var props = null;
|
||||
if (def ? (def.key = "", is("punc", ",") && next()) : !is("string")) {
|
||||
var cont;
|
||||
if (def) {
|
||||
def.key = new AST_String({
|
||||
start: def.start,
|
||||
value: "",
|
||||
end: def.end,
|
||||
});
|
||||
if (cont = is("punc", ",")) next();
|
||||
} else {
|
||||
cont = !is("string");
|
||||
}
|
||||
if (cont) {
|
||||
if (is("operator", "*")) {
|
||||
var key = S.token;
|
||||
next();
|
||||
expect_token("name", "as");
|
||||
all = as_symbol(AST_SymbolImport);
|
||||
all.key = "*";
|
||||
all.key = make_string(key);
|
||||
} else {
|
||||
expect("{");
|
||||
props = [];
|
||||
while (is_alias()) {
|
||||
var alias;
|
||||
if (is_token(peek(), "name", "as")) {
|
||||
var key = S.token.value;
|
||||
var key = S.token;
|
||||
next();
|
||||
next();
|
||||
alias = as_symbol(AST_SymbolImport);
|
||||
alias.key = key;
|
||||
alias.key = make_string(key);
|
||||
} else {
|
||||
alias = as_symbol(AST_SymbolImport);
|
||||
alias.key = alias.name;
|
||||
alias.key = new AST_String({
|
||||
start: alias.start,
|
||||
value: alias.name,
|
||||
end: alias.end,
|
||||
});
|
||||
}
|
||||
props.push(alias);
|
||||
if (!is("punc", "}")) expect(",");
|
||||
@@ -1622,15 +1637,11 @@ function parse($TEXT, options) {
|
||||
}
|
||||
}
|
||||
if (all || def || props) expect_token("name", "from");
|
||||
var path = S.token;
|
||||
expect_token("string");
|
||||
semicolon();
|
||||
return new AST_Import({
|
||||
all: all,
|
||||
default: def,
|
||||
path: path.value,
|
||||
path: as_path(),
|
||||
properties: props,
|
||||
quote: path.quote,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1808,7 +1819,7 @@ function parse($TEXT, options) {
|
||||
ret = new AST_BigInt({ value: value });
|
||||
break;
|
||||
case "string":
|
||||
ret = new AST_String({ value : value, quote : tok.quote });
|
||||
ret = new AST_String({ value: value, quote: tok.quote });
|
||||
break;
|
||||
case "regexp":
|
||||
ret = new AST_RegExp({ value: value });
|
||||
@@ -2160,9 +2171,9 @@ function parse($TEXT, options) {
|
||||
token_error(sym.start, "Unexpected " + sym.name + " in strict mode");
|
||||
}
|
||||
|
||||
function as_symbol(type, noerror) {
|
||||
function as_symbol(type, no_error) {
|
||||
if (!is("name")) {
|
||||
if (!noerror) croak("Name expected");
|
||||
if (!no_error) croak("Name expected");
|
||||
return null;
|
||||
}
|
||||
var sym = _make_symbol(type, S.token);
|
||||
@@ -2398,20 +2409,20 @@ function parse($TEXT, options) {
|
||||
return new ctor({ operator: op, expression: expr });
|
||||
}
|
||||
|
||||
var expr_op = function(left, min_prec, no_in) {
|
||||
var expr_op = function(left, min_precision, no_in) {
|
||||
var op = is("operator") ? S.token.value : null;
|
||||
if (op == "in" && no_in) op = null;
|
||||
var prec = op != null ? PRECEDENCE[op] : null;
|
||||
if (prec != null && prec > min_prec) {
|
||||
var precision = op != null ? PRECEDENCE[op] : null;
|
||||
if (precision != null && precision > min_precision) {
|
||||
next();
|
||||
var right = expr_op(maybe_unary(no_in), op == "**" ? prec - 1 : prec, no_in);
|
||||
var right = expr_op(maybe_unary(no_in), op == "**" ? precision - 1 : precision, no_in);
|
||||
return expr_op(new AST_Binary({
|
||||
start : left.start,
|
||||
left : left,
|
||||
operator : op,
|
||||
right : right,
|
||||
end : right.end
|
||||
}), min_prec, no_in);
|
||||
end : right.end,
|
||||
}), min_precision, no_in);
|
||||
}
|
||||
return left;
|
||||
};
|
||||
@@ -2563,7 +2574,7 @@ function parse($TEXT, options) {
|
||||
}
|
||||
S.input.push_directives_stack();
|
||||
while (!is("eof"))
|
||||
body.push(statement());
|
||||
body.push(statement(true));
|
||||
S.input.pop_directives_stack();
|
||||
var end = prev() || start;
|
||||
var toplevel = options.toplevel;
|
||||
|
||||
@@ -43,10 +43,11 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
var builtins = function() {
|
||||
function get_builtins() {
|
||||
var names = new Dictionary();
|
||||
// NaN will be included due to Number.NaN
|
||||
// constants
|
||||
[
|
||||
"NaN",
|
||||
"null",
|
||||
"true",
|
||||
"false",
|
||||
@@ -54,37 +55,85 @@ var builtins = function() {
|
||||
"-Infinity",
|
||||
"undefined",
|
||||
].forEach(add);
|
||||
// global functions
|
||||
[
|
||||
Array,
|
||||
Boolean,
|
||||
Date,
|
||||
Error,
|
||||
Function,
|
||||
Math,
|
||||
Number,
|
||||
Object,
|
||||
RegExp,
|
||||
String,
|
||||
].forEach(function(ctor) {
|
||||
"encodeURI",
|
||||
"encodeURIComponent",
|
||||
"escape",
|
||||
"eval",
|
||||
"decodeURI",
|
||||
"decodeURIComponent",
|
||||
"isFinite",
|
||||
"isNaN",
|
||||
"parseFloat",
|
||||
"parseInt",
|
||||
"unescape",
|
||||
].forEach(add);
|
||||
// global constructors & objects
|
||||
var global = Function("return this")();
|
||||
[
|
||||
"Array",
|
||||
"ArrayBuffer",
|
||||
"Atomics",
|
||||
"BigInt",
|
||||
"Boolean",
|
||||
"console",
|
||||
"DataView",
|
||||
"Date",
|
||||
"Error",
|
||||
"Function",
|
||||
"Int8Array",
|
||||
"Intl",
|
||||
"JSON",
|
||||
"Map",
|
||||
"Math",
|
||||
"Number",
|
||||
"Object",
|
||||
"Promise",
|
||||
"Proxy",
|
||||
"Reflect",
|
||||
"RegExp",
|
||||
"Set",
|
||||
"String",
|
||||
"Symbol",
|
||||
"WebAssembly",
|
||||
].forEach(function(name) {
|
||||
add(name);
|
||||
var ctor = global[name];
|
||||
if (!ctor) return;
|
||||
Object.getOwnPropertyNames(ctor).map(add);
|
||||
if (ctor.prototype) {
|
||||
if (typeof ctor != "function") return;
|
||||
if (ctor.__proto__) Object.getOwnPropertyNames(ctor.__proto__).map(add);
|
||||
if (ctor.prototype) Object.getOwnPropertyNames(ctor.prototype).map(add);
|
||||
try {
|
||||
Object.getOwnPropertyNames(new ctor()).map(add);
|
||||
Object.getOwnPropertyNames(ctor.prototype).map(add);
|
||||
} catch (e) {
|
||||
try {
|
||||
Object.getOwnPropertyNames(ctor()).map(add);
|
||||
} catch (e) {}
|
||||
}
|
||||
});
|
||||
return names;
|
||||
return (get_builtins = function() {
|
||||
return names.clone();
|
||||
})();
|
||||
|
||||
function add(name) {
|
||||
names.set(name, true);
|
||||
}
|
||||
}();
|
||||
}
|
||||
|
||||
function reserve_quoted_keys(ast, reserved) {
|
||||
ast.walk(new TreeWalker(function(node) {
|
||||
if (node instanceof AST_ClassProperty) {
|
||||
if (node.start && node.start.quote) add(node.key);
|
||||
} else if (node instanceof AST_ObjectProperty) {
|
||||
if (node.start && node.start.quote) add(node.key);
|
||||
if (node instanceof AST_ClassProperty
|
||||
|| node instanceof AST_DestructuredKeyVal
|
||||
|| node instanceof AST_ObjectProperty) {
|
||||
if (node.key instanceof AST_Node) {
|
||||
addStrings(node.key, add);
|
||||
} else if (node.start && node.start.quote) {
|
||||
add(node.key);
|
||||
}
|
||||
} else if (node instanceof AST_Dot) {
|
||||
if (node.quoted) add(node.property);
|
||||
} else if (node instanceof AST_Sub) {
|
||||
addStrings(node.property, add);
|
||||
}
|
||||
@@ -111,12 +160,16 @@ function mangle_properties(ast, options) {
|
||||
builtins: false,
|
||||
cache: null,
|
||||
debug: false,
|
||||
domprops: false,
|
||||
keep_quoted: false,
|
||||
regex: null,
|
||||
reserved: null,
|
||||
}, true);
|
||||
|
||||
var reserved = options.builtins ? new Dictionary() : builtins.clone();
|
||||
var reserved = options.builtins ? new Dictionary() : get_builtins();
|
||||
if (!options.domprops && typeof domprops !== "undefined") domprops.forEach(function(name) {
|
||||
reserved.set(name, true);
|
||||
});
|
||||
if (Array.isArray(options.reserved)) options.reserved.forEach(function(name) {
|
||||
reserved.set(name, true);
|
||||
});
|
||||
@@ -135,7 +188,7 @@ function mangle_properties(ast, options) {
|
||||
var regex = options.regex;
|
||||
|
||||
// note debug is either false (disabled), or a string of the debug suffix to use (enabled).
|
||||
// note debug may be enabled as an empty string, which is falsey. Also treat passing 'true'
|
||||
// note debug may be enabled as an empty string, which is falsy. Also treat passing 'true'
|
||||
// the same as passing an empty string.
|
||||
var debug = options.debug !== false;
|
||||
var debug_suffix;
|
||||
@@ -146,9 +199,7 @@ function mangle_properties(ast, options) {
|
||||
|
||||
// step 1: find candidates to mangle
|
||||
ast.walk(new TreeWalker(function(node) {
|
||||
if (node instanceof AST_Binary) {
|
||||
if (node.operator == "in") addStrings(node.left, add);
|
||||
} else if (node.TYPE == "Call") {
|
||||
if (node.TYPE == "Call") {
|
||||
var exp = node.expression;
|
||||
if (exp instanceof AST_Dot) switch (exp.property) {
|
||||
case "defineProperty":
|
||||
@@ -165,14 +216,18 @@ function mangle_properties(ast, options) {
|
||||
addStrings(node.args[0], add);
|
||||
break;
|
||||
}
|
||||
} else if (node instanceof AST_ClassProperty) {
|
||||
if (typeof node.key == "string") add(node.key);
|
||||
} else if (node instanceof AST_ClassProperty
|
||||
|| node instanceof AST_DestructuredKeyVal
|
||||
|| node instanceof AST_ObjectProperty) {
|
||||
if (node.key instanceof AST_Node) {
|
||||
addStrings(node.key, add);
|
||||
} else {
|
||||
add(node.key);
|
||||
}
|
||||
} else if (node instanceof AST_Dot) {
|
||||
add(node.property);
|
||||
} else if (node instanceof AST_ObjectProperty) {
|
||||
if (typeof node.key == "string") add(node.key);
|
||||
if (is_lhs(node, this.parent())) add(node.property);
|
||||
} else if (node instanceof AST_Sub) {
|
||||
addStrings(node.property, add);
|
||||
if (is_lhs(node, this.parent())) addStrings(node.property, add);
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -197,12 +252,16 @@ function mangle_properties(ast, options) {
|
||||
mangleStrings(node.args[0]);
|
||||
break;
|
||||
}
|
||||
} else if (node instanceof AST_ClassProperty) {
|
||||
if (typeof node.key == "string") node.key = mangle(node.key);
|
||||
} else if (node instanceof AST_ClassProperty
|
||||
|| node instanceof AST_DestructuredKeyVal
|
||||
|| node instanceof AST_ObjectProperty) {
|
||||
if (node.key instanceof AST_Node) {
|
||||
mangleStrings(node.key);
|
||||
} else {
|
||||
node.key = mangle(node.key);
|
||||
}
|
||||
} else if (node instanceof AST_Dot) {
|
||||
node.property = mangle(node.property);
|
||||
} else if (node instanceof AST_ObjectProperty) {
|
||||
if (typeof node.key == "string") node.key = mangle(node.key);
|
||||
} else if (node instanceof AST_Sub) {
|
||||
if (!options.keep_quoted) mangleStrings(node.property);
|
||||
}
|
||||
@@ -217,8 +276,14 @@ function mangle_properties(ast, options) {
|
||||
}
|
||||
|
||||
function should_mangle(name) {
|
||||
if (reserved.has(name)) return false;
|
||||
if (regex && !regex.test(name)) return false;
|
||||
if (reserved.has(name)) {
|
||||
AST_Node.info("Preserving reserved property {this}", name);
|
||||
return false;
|
||||
}
|
||||
if (regex && !regex.test(name)) {
|
||||
AST_Node.info("Preserving excluded property {this}", name);
|
||||
return false;
|
||||
}
|
||||
return cache.has(name) || names_to_mangle.has(name);
|
||||
}
|
||||
|
||||
@@ -243,12 +308,16 @@ function mangle_properties(ast, options) {
|
||||
if (/^#/.test(name)) mangled = "#" + mangled;
|
||||
cache.set(name, mangled);
|
||||
}
|
||||
AST_Node.info("Mapping property {name} to {mangled}", {
|
||||
mangled: mangled,
|
||||
name: name,
|
||||
});
|
||||
return mangled;
|
||||
}
|
||||
|
||||
function mangleStrings(node) {
|
||||
if (node instanceof AST_Sequence) {
|
||||
mangleStrings(node.expressions.tail_node());
|
||||
mangleStrings(node.tail_node());
|
||||
} else if (node instanceof AST_String) {
|
||||
node.value = mangle(node.value);
|
||||
} else if (node instanceof AST_Conditional) {
|
||||
|
||||
83
lib/scope.js
83
lib/scope.js
@@ -68,9 +68,7 @@ SymbolDef.prototype = {
|
||||
var cache = this.global && options.cache && options.cache.props;
|
||||
if (cache && cache.has(this.name)) {
|
||||
this.mangled_name = cache.get(this.name);
|
||||
} else if (this.unmangleable(options)) {
|
||||
names_in_use(this.scope, options).set(this.name, true);
|
||||
} else {
|
||||
} else if (!this.unmangleable(options)) {
|
||||
var def = this.redefined();
|
||||
if (def) {
|
||||
this.mangled_name = def.mangled_name || def.name;
|
||||
@@ -180,6 +178,13 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
||||
});
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_Switch) {
|
||||
node.expression.walk(tw);
|
||||
walk_scope(function() {
|
||||
walk_body(node, tw);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_SwitchBranch) {
|
||||
node.init_vars(scope);
|
||||
descend();
|
||||
@@ -286,7 +291,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
||||
// ensure mangling works if `catch` reuses a scope variable
|
||||
var redef = def.redefined();
|
||||
if (redef) for (var s = node.scope; s; s = s.parent_scope) {
|
||||
push_uniq(s.enclosed, redef);
|
||||
if (!push_uniq(s.enclosed, redef)) break;
|
||||
if (s === redef.scope) break;
|
||||
}
|
||||
} else if (node instanceof AST_SymbolConst) {
|
||||
@@ -369,8 +374,9 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
||||
// pass 3: fix up any scoping issue with IE8
|
||||
if (options.ie) self.walk(new TreeWalker(function(node) {
|
||||
if (node instanceof AST_SymbolCatch) {
|
||||
var scope = node.thedef.defun;
|
||||
if (scope.name instanceof AST_SymbolLambda && scope.name.name == node.name) {
|
||||
var def = node.thedef;
|
||||
var scope = def.defun;
|
||||
if (def.name != "arguments" && scope.name instanceof AST_SymbolLambda && scope.name.name == def.name) {
|
||||
scope = scope.parent_scope.resolve();
|
||||
}
|
||||
redefine(node, scope);
|
||||
@@ -438,35 +444,43 @@ AST_Toplevel.DEFMETHOD("def_global", function(node) {
|
||||
}
|
||||
});
|
||||
|
||||
function init_block_vars(scope, parent) {
|
||||
scope.enclosed = []; // variables from this or outer scope(s) that are referenced from this or inner scopes
|
||||
scope.parent_scope = parent; // the parent scope (null if this is the top level)
|
||||
scope.functions = new Dictionary(); // map name to AST_SymbolDefun (functions defined in this scope)
|
||||
scope.variables = new Dictionary(); // map name to AST_SymbolVar (variables defined in this scope; includes functions)
|
||||
if (parent) scope.make_def = parent.make_def; // top-level tracking of SymbolDef instances
|
||||
function init_block_vars(scope, parent, orig) {
|
||||
// variables from this or outer scope(s) that are referenced from this or inner scopes
|
||||
scope.enclosed = orig ? orig.enclosed.slice() : [];
|
||||
// map name to AST_SymbolDefun (functions defined in this scope)
|
||||
scope.functions = orig ? orig.functions.clone() : new Dictionary();
|
||||
// map name to AST_SymbolVar (variables defined in this scope; includes functions)
|
||||
scope.variables = orig ? orig.variables.clone() : new Dictionary();
|
||||
if (!parent) return;
|
||||
// top-level tracking of SymbolDef instances
|
||||
scope.make_def = parent.make_def;
|
||||
// the parent scope (null if this is the top level)
|
||||
scope.parent_scope = parent;
|
||||
}
|
||||
|
||||
function init_scope_vars(scope, parent) {
|
||||
init_block_vars(scope, parent);
|
||||
scope.uses_eval = false; // will be set to true if this or nested scope uses the global `eval`
|
||||
scope.uses_with = false; // will be set to true if this or some nested scope uses the `with` statement
|
||||
function init_scope_vars(scope, parent, orig) {
|
||||
init_block_vars(scope, parent, orig);
|
||||
// will be set to true if this or nested scope uses the global `eval`
|
||||
scope.uses_eval = false;
|
||||
// will be set to true if this or some nested scope uses the `with` statement
|
||||
scope.uses_with = false;
|
||||
}
|
||||
|
||||
AST_BlockScope.DEFMETHOD("init_vars", function(parent_scope) {
|
||||
init_block_vars(this, parent_scope);
|
||||
AST_BlockScope.DEFMETHOD("init_vars", function(parent, orig) {
|
||||
init_block_vars(this, parent, orig);
|
||||
});
|
||||
AST_Scope.DEFMETHOD("init_vars", function(parent_scope) {
|
||||
init_scope_vars(this, parent_scope);
|
||||
AST_Scope.DEFMETHOD("init_vars", function(parent, orig) {
|
||||
init_scope_vars(this, parent, orig);
|
||||
});
|
||||
AST_Arrow.DEFMETHOD("init_vars", function(parent_scope) {
|
||||
init_scope_vars(this, parent_scope);
|
||||
AST_Arrow.DEFMETHOD("init_vars", function(parent, orig) {
|
||||
init_scope_vars(this, parent, orig);
|
||||
return this;
|
||||
});
|
||||
AST_AsyncArrow.DEFMETHOD("init_vars", function(parent_scope) {
|
||||
init_scope_vars(this, parent_scope);
|
||||
AST_AsyncArrow.DEFMETHOD("init_vars", function(parent, orig) {
|
||||
init_scope_vars(this, parent, orig);
|
||||
});
|
||||
AST_Lambda.DEFMETHOD("init_vars", function(parent_scope) {
|
||||
init_scope_vars(this, parent_scope);
|
||||
AST_Lambda.DEFMETHOD("init_vars", function(parent, orig) {
|
||||
init_scope_vars(this, parent, orig);
|
||||
this.uses_arguments = false;
|
||||
this.def_variable(new AST_SymbolFunarg({
|
||||
name: "arguments",
|
||||
@@ -480,7 +494,7 @@ AST_Lambda.DEFMETHOD("init_vars", function(parent_scope) {
|
||||
AST_Symbol.DEFMETHOD("mark_enclosed", function(options) {
|
||||
var def = this.definition();
|
||||
for (var s = this.scope; s; s = s.parent_scope) {
|
||||
push_uniq(s.enclosed, def);
|
||||
if (!push_uniq(s.enclosed, def)) break;
|
||||
if (!options) {
|
||||
s._var_names = undefined;
|
||||
} else {
|
||||
@@ -642,8 +656,12 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
|
||||
}, true);
|
||||
}
|
||||
var to_mangle = node.to_mangle = [];
|
||||
node.variables.each(function(def) {
|
||||
if (!defer_redef(def)) to_mangle.push(def);
|
||||
node.variables.each(function(def, name) {
|
||||
if (def.unmangleable(options)) {
|
||||
names_in_use(node, options).set(name, true);
|
||||
} else if (!defer_redef(def)) {
|
||||
to_mangle.push(def);
|
||||
}
|
||||
});
|
||||
descend();
|
||||
if (options.cache && node instanceof AST_Toplevel) {
|
||||
@@ -704,7 +722,12 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
|
||||
}
|
||||
redefined.push(def);
|
||||
def.references.forEach(reference);
|
||||
if (sym instanceof AST_SymbolCatch || sym instanceof AST_SymbolConst) reference(sym);
|
||||
if (sym instanceof AST_SymbolCatch || sym instanceof AST_SymbolConst) {
|
||||
reference(sym);
|
||||
def.redefined = function() {
|
||||
return redef;
|
||||
};
|
||||
}
|
||||
return true;
|
||||
|
||||
function reference(sym) {
|
||||
|
||||
39
lib/utils.js
39
lib/utils.js
@@ -55,28 +55,41 @@ function find_if(func, array) {
|
||||
for (var i = array.length; --i >= 0;) if (func(array[i])) return array[i];
|
||||
}
|
||||
|
||||
function configure_error_stack(fn) {
|
||||
Object.defineProperty(fn.prototype, "stack", {
|
||||
function configure_error_stack(ex, cause) {
|
||||
var stack = ex.name + ": " + ex.message;
|
||||
Object.defineProperty(ex, "stack", {
|
||||
get: function() {
|
||||
var err = new Error(this.message);
|
||||
err.name = this.name;
|
||||
try {
|
||||
throw err;
|
||||
} catch (e) {
|
||||
return e.stack;
|
||||
if (cause) {
|
||||
cause.name = "" + ex.name;
|
||||
stack = "" + cause.stack;
|
||||
var msg = "" + cause.message;
|
||||
cause = null;
|
||||
var index = stack.indexOf(msg);
|
||||
if (index < 0) {
|
||||
index = 0;
|
||||
} else {
|
||||
index += msg.length;
|
||||
index = stack.indexOf("\n", index) + 1;
|
||||
}
|
||||
stack = stack.slice(0, index) + stack.slice(stack.indexOf("\n", index) + 1);
|
||||
}
|
||||
}
|
||||
return stack;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function DefaultsError(msg, defs) {
|
||||
this.message = msg;
|
||||
this.defs = defs;
|
||||
try {
|
||||
throw new Error(msg);
|
||||
} catch (cause) {
|
||||
configure_error_stack(this, cause);
|
||||
}
|
||||
}
|
||||
DefaultsError.prototype = Object.create(Error.prototype);
|
||||
DefaultsError.prototype.constructor = DefaultsError;
|
||||
DefaultsError.prototype.name = "DefaultsError";
|
||||
configure_error_stack(DefaultsError);
|
||||
|
||||
function defaults(args, defs, croak) {
|
||||
if (croak) for (var i in args) {
|
||||
@@ -127,8 +140,10 @@ function push_uniq(array, el) {
|
||||
|
||||
function string_template(text, props) {
|
||||
return text.replace(/\{([^{}]+)\}/g, function(str, p) {
|
||||
var value = props[p];
|
||||
return value instanceof AST_Node ? value.print_to_string() : value;
|
||||
var value = p == "this" ? props : props[p];
|
||||
if (value instanceof AST_Node) return value.print_to_string();
|
||||
if (value instanceof AST_Token) return value.file + ":" + value.line + "," + value.col;
|
||||
return value;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||
"license": "BSD-2-Clause",
|
||||
"version": "3.16.1",
|
||||
"version": "3.18.0",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
},
|
||||
@@ -23,7 +23,7 @@
|
||||
"LICENSE"
|
||||
],
|
||||
"devDependencies": {
|
||||
"acorn": "~8.2.1",
|
||||
"acorn": "~8.7.1",
|
||||
"semver": "~6.3.0"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
require("../tools/tty");
|
||||
var createHash = require("crypto").createHash;
|
||||
var fetch = require("./fetch");
|
||||
var spawn = require("child_process").spawn;
|
||||
|
||||
@@ -60,8 +60,9 @@ function log() {
|
||||
console.log("%s", tmpl.apply(null, arguments));
|
||||
}
|
||||
|
||||
function make_code(ast, options) {
|
||||
function make_code(ast, options, expression) {
|
||||
var stream = U.OutputStream(options);
|
||||
if (expression) ast = ast.clone(true).unwrap_expression();
|
||||
ast.print(stream);
|
||||
return stream.get();
|
||||
}
|
||||
@@ -69,7 +70,7 @@ function make_code(ast, options) {
|
||||
function parse_test(file) {
|
||||
var script = fs.readFileSync(file, "utf8");
|
||||
try {
|
||||
var ast = U.parse(script, { filename: file });
|
||||
var ast = U.parse(script, { filename: file, module: "" });
|
||||
} catch (e) {
|
||||
console.error("Caught error while parsing tests in " + file);
|
||||
console.error(e);
|
||||
@@ -125,6 +126,17 @@ function parse_test(file) {
|
||||
croak(node);
|
||||
}
|
||||
var name = node.left.name;
|
||||
assert.ok([
|
||||
"beautify",
|
||||
"expression",
|
||||
"mangle",
|
||||
"options",
|
||||
"rename",
|
||||
].indexOf(name) >= 0, tmpl("Unsupported setting {name} [{line},{col}]", {
|
||||
name: name,
|
||||
line: node.start.line,
|
||||
col: node.start.col,
|
||||
}));
|
||||
test[name] = evaluate(node.right);
|
||||
return true;
|
||||
}
|
||||
@@ -178,9 +190,18 @@ function parse_test(file) {
|
||||
|
||||
// Try to reminify original input with standard options
|
||||
// to see if it matches expect_stdout.
|
||||
function reminify(orig_options, input_code, input_formatted, stdout) {
|
||||
function reminify(expression, orig_options, input_code, input_formatted, stdout) {
|
||||
for (var i = 0; i < minify_options.length; i++) {
|
||||
var options = JSON.parse(minify_options[i]);
|
||||
if (expression) {
|
||||
if (!options.parse || typeof options.parse != "object") options.parse = {};
|
||||
options.parse.expression = true;
|
||||
if (options.compress == null) options.compress = {};
|
||||
if (options.compress) {
|
||||
if (typeof options.compress != "object") options.compress = {};
|
||||
options.compress.expression = true;
|
||||
}
|
||||
}
|
||||
[
|
||||
"keep_fargs",
|
||||
"keep_fnames",
|
||||
@@ -210,7 +231,7 @@ function reminify(orig_options, input_code, input_formatted, stdout) {
|
||||
} else {
|
||||
var toplevel = sandbox.has_toplevel(options);
|
||||
var expected = stdout[toplevel ? 1 : 0];
|
||||
var actual = sandbox.run_code(result.code, toplevel);
|
||||
var actual = run_code(expression, result.code, toplevel);
|
||||
if (typeof expected != "string" && typeof actual != "string" && expected.name == actual.name) {
|
||||
actual = expected;
|
||||
}
|
||||
@@ -245,18 +266,25 @@ function reminify(orig_options, input_code, input_formatted, stdout) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function run_code(expression, code, toplevel) {
|
||||
return sandbox.run_code(expression ? "console.log(" + code + ");" : code, toplevel);
|
||||
}
|
||||
|
||||
function test_case(test) {
|
||||
log(" Running test [{name}]", { name: test.name });
|
||||
U.AST_Node.enable_validation();
|
||||
var output_options = test.beautify || {};
|
||||
var expect;
|
||||
if (test.expect) {
|
||||
expect = make_code(to_toplevel(test.expect, test.mangle), output_options);
|
||||
expect = to_toplevel(test.expect, test.mangle, test.expression);
|
||||
expect = make_code(expect, output_options, test.expression);
|
||||
} else {
|
||||
expect = test.expect_exact;
|
||||
}
|
||||
var input = to_toplevel(test.input, test.mangle);
|
||||
var input_code = make_code(input);
|
||||
var input = to_toplevel(test.input, test.mangle, test.expression);
|
||||
var input_code = make_code(input, {
|
||||
keep_quoted_props: true,
|
||||
}, test.expression);
|
||||
var input_formatted = make_code(test.input, {
|
||||
annotations: true,
|
||||
beautify: true,
|
||||
@@ -266,7 +294,7 @@ function test_case(test) {
|
||||
});
|
||||
try {
|
||||
input.validate_ast();
|
||||
U.parse(input_code);
|
||||
U.parse(input_code, { expression: test.expression });
|
||||
} catch (ex) {
|
||||
log([
|
||||
"!!! Cannot parse input",
|
||||
@@ -292,8 +320,9 @@ function test_case(test) {
|
||||
warnings_emitted.push(text);
|
||||
}, /"INFO: /.test(expected_warnings));
|
||||
}
|
||||
var quoted_props;
|
||||
if (test.mangle && test.mangle.properties && test.mangle.properties.keep_quoted) {
|
||||
var quoted_props = test.mangle.properties.reserved;
|
||||
quoted_props = test.mangle.properties.reserved;
|
||||
if (!Array.isArray(quoted_props)) quoted_props = [];
|
||||
test.mangle.properties.reserved = quoted_props;
|
||||
U.reserve_quoted_keys(input, quoted_props);
|
||||
@@ -308,9 +337,10 @@ function test_case(test) {
|
||||
if (test.mangle) {
|
||||
output.compute_char_frequency(test.mangle);
|
||||
output.mangle_names(test.mangle);
|
||||
if (quoted_props) U.reserve_quoted_keys(input, quoted_props);
|
||||
if (test.mangle.properties) U.mangle_properties(output, test.mangle.properties);
|
||||
}
|
||||
var output_code = make_code(output, output_options);
|
||||
var output_code = make_code(output, output_options, test.expression);
|
||||
U.AST_Node.log_function();
|
||||
if (expect != output_code) {
|
||||
log([
|
||||
@@ -333,7 +363,7 @@ function test_case(test) {
|
||||
// expect == output
|
||||
try {
|
||||
output.validate_ast();
|
||||
U.parse(output_code);
|
||||
U.parse(output_code, { expression: test.expression });
|
||||
} catch (ex) {
|
||||
log([
|
||||
"!!! Test matched expected result but cannot parse output",
|
||||
@@ -377,7 +407,7 @@ function test_case(test) {
|
||||
}
|
||||
}
|
||||
if (test.expect_stdout && (!test.node_version || semver.satisfies(process.version, test.node_version))) {
|
||||
var stdout = [ sandbox.run_code(input_code), sandbox.run_code(input_code, true) ];
|
||||
var stdout = [ run_code(test.expression, input_code), run_code(test.expression, input_code, true) ];
|
||||
var toplevel = sandbox.has_toplevel({
|
||||
compress: test.options,
|
||||
mangle: test.mangle
|
||||
@@ -406,7 +436,7 @@ function test_case(test) {
|
||||
});
|
||||
return false;
|
||||
}
|
||||
actual = sandbox.run_code(output_code, toplevel);
|
||||
actual = run_code(test.expression, output_code, toplevel);
|
||||
if (!sandbox.same_stdout(test.expect_stdout, actual)) {
|
||||
log([
|
||||
"!!! failed",
|
||||
@@ -427,7 +457,7 @@ function test_case(test) {
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!reminify(test.options, input_code, input_formatted, stdout)) {
|
||||
if (!reminify(test.expression, test.options, input_code, input_formatted, stdout)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -438,20 +468,30 @@ function tmpl() {
|
||||
return U.string_template.apply(null, arguments);
|
||||
}
|
||||
|
||||
function to_toplevel(input, mangle_options) {
|
||||
function to_toplevel(input, mangle_options, expression) {
|
||||
if (!(input instanceof U.AST_BlockStatement)) throw new Error("Unsupported input syntax");
|
||||
var directive = true;
|
||||
var offset = input.start.line;
|
||||
var tokens = [];
|
||||
var toplevel = new U.AST_Toplevel(input.transform(new U.TreeTransformer(function(node) {
|
||||
input.walk(new U.TreeWalker(function(node) {
|
||||
if (U.push_uniq(tokens, node.start)) node.start.line -= offset;
|
||||
if (!directive || node === input) return;
|
||||
if (node instanceof U.AST_SimpleStatement && node.body instanceof U.AST_String) {
|
||||
return new U.AST_Directive(node.body);
|
||||
} else {
|
||||
if (U.push_uniq(tokens, node.end)) node.end.line -= offset;
|
||||
}));
|
||||
var toplevel;
|
||||
if (!expression) {
|
||||
var directive = true;
|
||||
toplevel = new U.AST_Toplevel(input.transform(new U.TreeTransformer(function(node) {
|
||||
if (!directive) return node;
|
||||
if (node === input) return;
|
||||
if (node instanceof U.AST_SimpleStatement && node.body instanceof U.AST_String) {
|
||||
return new U.AST_Directive(node.body);
|
||||
}
|
||||
directive = false;
|
||||
}
|
||||
})));
|
||||
})));
|
||||
} else if (input.body.length == 1) {
|
||||
toplevel = input.body[0].wrap_expression();
|
||||
} else {
|
||||
throw new Error("Invalid expression");
|
||||
}
|
||||
toplevel.figure_out_scope(mangle_options);
|
||||
return toplevel;
|
||||
}
|
||||
|
||||
@@ -668,6 +668,87 @@ single_use_recursive: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
inline_iife_within_arrow: {
|
||||
options = {
|
||||
arrows: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
var f = () => console.log(function(a) {
|
||||
return Math.ceil(a);
|
||||
}(Math.random()));
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
var f = () => {
|
||||
return console.log((a = Math.random(), Math.ceil(a)));
|
||||
var a;
|
||||
};
|
||||
f();
|
||||
}
|
||||
expect_stdout: "1"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
instanceof_lambda_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
console.log(42 instanceof (() => {}));
|
||||
}
|
||||
expect: {
|
||||
console.log(false);
|
||||
}
|
||||
expect_stdout: "false"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
instanceof_lambda_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
side_effects: false,
|
||||
}
|
||||
input: {
|
||||
console.log(null instanceof (() => {}));
|
||||
}
|
||||
expect: {
|
||||
console.log((null, () => {}, false));
|
||||
}
|
||||
expect_stdout: "false"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
instanceof_lambda_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
console.log({} instanceof (() => {}));
|
||||
}
|
||||
expect: {
|
||||
console.log({} instanceof (() => {}));
|
||||
}
|
||||
expect_stdout: TypeError("Function has non-object prototype 'undefined' in instanceof check")
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
instanceof_lambda_4: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
({ p: "foo" }) instanceof (() => {});
|
||||
}
|
||||
expect: {
|
||||
[] instanceof (() => {});
|
||||
}
|
||||
expect_stdout: TypeError("Function has non-object prototype 'undefined' in instanceof check")
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_4388: {
|
||||
options = {
|
||||
inline: true,
|
||||
@@ -1073,7 +1154,7 @@ issue_5414_2: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5416: {
|
||||
issue_5416_1: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
@@ -1095,10 +1176,11 @@ issue_5416: {
|
||||
expect: {
|
||||
var f = () => {
|
||||
{
|
||||
arguments = void 0;
|
||||
console;
|
||||
arguments = void 0,
|
||||
console.log(arguments);
|
||||
var arguments;
|
||||
return;
|
||||
}
|
||||
};
|
||||
f();
|
||||
@@ -1107,6 +1189,97 @@ issue_5416: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5416_2: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
loops: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var f = () => {
|
||||
while ((() => {
|
||||
console;
|
||||
var a = function g(arguments) {
|
||||
while (console.log(arguments));
|
||||
}();
|
||||
})());
|
||||
};
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
var f = () => {
|
||||
{
|
||||
console;
|
||||
var arguments = void 0;
|
||||
for (; console.log(arguments););
|
||||
return;
|
||||
}
|
||||
};
|
||||
f();
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5416_3: {
|
||||
options = {
|
||||
inline: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var f = () => {
|
||||
(() => {
|
||||
var a = function g(arguments) {
|
||||
console.log(arguments);
|
||||
}();
|
||||
})();
|
||||
};
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
var f = () => {
|
||||
arguments = void 0,
|
||||
console.log(arguments);
|
||||
var arguments;
|
||||
};
|
||||
f();
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5416_4: {
|
||||
options = {
|
||||
arrows: true,
|
||||
inline: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var f = () => {
|
||||
(() => {
|
||||
var a = function g(arguments) {
|
||||
while (console.log(arguments));
|
||||
}();
|
||||
})();
|
||||
};
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
var f = () => {
|
||||
var arguments = void 0;
|
||||
while (console.log(arguments));
|
||||
return;
|
||||
};
|
||||
f();
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5495: {
|
||||
input: {
|
||||
console.log((() => {
|
||||
@@ -1120,3 +1293,28 @@ issue_5495: {
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5653: {
|
||||
options = {
|
||||
arrows: true,
|
||||
hoist_props: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log((a => {
|
||||
a = { p: console };
|
||||
return a++;
|
||||
})());
|
||||
}
|
||||
expect: {
|
||||
console.log((a => {
|
||||
return +{};
|
||||
})());
|
||||
}
|
||||
expect_stdout: "NaN"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
@@ -290,6 +290,45 @@ increment_decrement_2: {
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
lazily_chained_assignments: {
|
||||
options = {
|
||||
assignments: true,
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
if (a = console.log("foo"))
|
||||
a = console.log("bar");
|
||||
return a;
|
||||
}
|
||||
function g(b) {
|
||||
if (b = console.log("baz"))
|
||||
;
|
||||
else
|
||||
b = console.log("moo");
|
||||
return b;
|
||||
}
|
||||
console.log(f(), g());
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
return console.log("foo") && console.log("bar");
|
||||
}
|
||||
function g(b) {
|
||||
return console.log("baz") || console.log("moo");
|
||||
}
|
||||
console.log(f(), g());
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"baz",
|
||||
"moo",
|
||||
"undefined undefined",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3375_1: {
|
||||
options = {
|
||||
assignments: true,
|
||||
@@ -803,3 +842,23 @@ issue_4924_2: {
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=15"
|
||||
}
|
||||
|
||||
issue_5670: {
|
||||
options = {
|
||||
assignments: true,
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
(function(a, b) {
|
||||
a && a && (a = b += "") || console.log("PASS");
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function(a, b) {
|
||||
a = a,
|
||||
console.log("PASS");
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -529,6 +529,7 @@ inline_block_await: {
|
||||
|
||||
inline_block_await_async: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
@@ -1046,6 +1047,60 @@ collapse_vars_3: {
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
collapse_funarg_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
A = "FAIL";
|
||||
var a = "PASS";
|
||||
(async function({}, b) {
|
||||
return b;
|
||||
})(null, A = a);
|
||||
console.log(A);
|
||||
}
|
||||
expect: {
|
||||
A = "FAIL";
|
||||
var a = "PASS";
|
||||
(async function({}, b) {
|
||||
return b;
|
||||
})(null, A = a);
|
||||
console.log(A);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
collapse_funarg_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
A = "FAIL";
|
||||
B = "PASS";
|
||||
(async function() {
|
||||
console.log(function({}, a) {
|
||||
return a;
|
||||
}(null, A = B));
|
||||
})();
|
||||
console.log(A);
|
||||
}
|
||||
expect: {
|
||||
A = "FAIL";
|
||||
B = "PASS";
|
||||
(async function() {
|
||||
console.log(function({}, a) {
|
||||
return a;
|
||||
}(null, A = B));
|
||||
})();
|
||||
console.log(A);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
collapse_property_lambda: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
@@ -1293,7 +1348,7 @@ functions_inner_var: {
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
instanceof_lambda: {
|
||||
instanceof_lambda_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
@@ -1308,6 +1363,50 @@ instanceof_lambda: {
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
instanceof_lambda_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
side_effects: false,
|
||||
}
|
||||
input: {
|
||||
console.log(null instanceof async function() {});
|
||||
}
|
||||
expect: {
|
||||
console.log((null, async function() {}, false));
|
||||
}
|
||||
expect_stdout: "false"
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
instanceof_lambda_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
console.log({} instanceof async function() {});
|
||||
}
|
||||
expect: {
|
||||
console.log({} instanceof async function() {});
|
||||
}
|
||||
expect_stdout: TypeError("Function has non-object prototype 'undefined' in instanceof check")
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
instanceof_lambda_4: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
({ p: "foo" }) instanceof async function() {};
|
||||
}
|
||||
expect: {
|
||||
[] instanceof async function() {};
|
||||
}
|
||||
expect_stdout: TypeError("Function has non-object prototype 'undefined' in instanceof check")
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_4335_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
@@ -2693,6 +2792,7 @@ issue_5177: {
|
||||
|
||||
issue_5250: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
@@ -2801,6 +2901,7 @@ issue_5298: {
|
||||
|
||||
issue_5305_1: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
@@ -2834,6 +2935,7 @@ issue_5305_1: {
|
||||
|
||||
issue_5305_2: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
@@ -3021,3 +3123,585 @@ issue_5506: {
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5528_1: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(async function() {
|
||||
await function() {
|
||||
try {
|
||||
return;
|
||||
} finally {
|
||||
console.log("foo");
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log("bar");
|
||||
}
|
||||
expect: {
|
||||
(async function() {
|
||||
await function() {
|
||||
try {
|
||||
return;
|
||||
} finally {
|
||||
console.log("foo");
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log("bar");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5528_2: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(async function() {
|
||||
await function() {
|
||||
try {
|
||||
return 42;
|
||||
} finally {
|
||||
console.log("foo");
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log("bar");
|
||||
}
|
||||
expect: {
|
||||
(async function() {
|
||||
await function() {
|
||||
try {
|
||||
return 42;
|
||||
} finally {
|
||||
console.log("foo");
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log("bar");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5528_3: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(async function() {
|
||||
await function() {
|
||||
try {
|
||||
FAIL;
|
||||
} catch (e) {
|
||||
return console.log("foo");
|
||||
} finally {
|
||||
console.log("bar");
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log("baz");
|
||||
}
|
||||
expect: {
|
||||
(async function() {
|
||||
await function() {
|
||||
try {
|
||||
FAIL;
|
||||
} catch (e) {
|
||||
return console.log("foo");
|
||||
} finally {
|
||||
console.log("bar");
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log("baz");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5528_4: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(async function() {
|
||||
await function() {
|
||||
try {
|
||||
return {
|
||||
then() {
|
||||
console.log("foo");
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
console.log("bar");
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log("baz");
|
||||
}
|
||||
expect: {
|
||||
(async function() {
|
||||
await function() {
|
||||
try {
|
||||
return {
|
||||
then() {
|
||||
console.log("foo");
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
console.log("bar");
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log("baz");
|
||||
}
|
||||
expect_stdout: [
|
||||
"bar",
|
||||
"baz",
|
||||
"foo",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5634_1: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
var a = "foo";
|
||||
(async function() {
|
||||
(async function() {
|
||||
try {
|
||||
return {
|
||||
then(resolve) {
|
||||
console.log("bar");
|
||||
resolve();
|
||||
console.log("baz");
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
a = "moo";
|
||||
}
|
||||
})();
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "foo";
|
||||
(async function() {
|
||||
(async function() {
|
||||
try {
|
||||
return {
|
||||
then(resolve) {
|
||||
console.log("bar");
|
||||
resolve();
|
||||
console.log("baz");
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
a = "moo";
|
||||
}
|
||||
})();
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: [
|
||||
"moo",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5634_1_side_effects: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var a = "foo";
|
||||
(async function() {
|
||||
(async function() {
|
||||
try {
|
||||
return {
|
||||
then(resolve) {
|
||||
console.log("bar");
|
||||
resolve();
|
||||
console.log("baz");
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
a = "moo";
|
||||
}
|
||||
})();
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "foo";
|
||||
(async function() {
|
||||
try {
|
||||
return {
|
||||
then(resolve) {
|
||||
console.log("bar");
|
||||
resolve();
|
||||
console.log("baz");
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
a = "moo";
|
||||
}
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: [
|
||||
"moo",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5634_2: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
var a = "foo";
|
||||
(async function() {
|
||||
await async function() {
|
||||
try {
|
||||
return {
|
||||
then(resolve) {
|
||||
console.log("bar");
|
||||
resolve();
|
||||
console.log("baz");
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
a = "moo";
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "foo";
|
||||
(async function() {
|
||||
await async function() {
|
||||
try {
|
||||
return {
|
||||
then(resolve) {
|
||||
console.log("bar");
|
||||
resolve();
|
||||
console.log("baz");
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
a = "moo";
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: [
|
||||
"moo",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5634_2_side_effects: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var a = "foo";
|
||||
(async function() {
|
||||
await async function() {
|
||||
try {
|
||||
return {
|
||||
then(resolve) {
|
||||
console.log("bar");
|
||||
resolve();
|
||||
console.log("baz");
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
a = "moo";
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "foo";
|
||||
(async function() {
|
||||
try {
|
||||
return {
|
||||
then(resolve) {
|
||||
console.log("bar");
|
||||
resolve();
|
||||
console.log("baz");
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
a = "moo";
|
||||
}
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: [
|
||||
"moo",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5634_3: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
var a = "foo";
|
||||
(async function() {
|
||||
return async function() {
|
||||
try {
|
||||
return {
|
||||
then(resolve) {
|
||||
console.log("bar");
|
||||
resolve();
|
||||
console.log("baz");
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
a = "moo";
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "foo";
|
||||
(async function() {
|
||||
return async function() {
|
||||
try {
|
||||
return {
|
||||
then(resolve) {
|
||||
console.log("bar");
|
||||
resolve();
|
||||
console.log("baz");
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
a = "moo";
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: [
|
||||
"moo",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5634_3_side_effects: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var a = "foo";
|
||||
(async function() {
|
||||
return async function() {
|
||||
try {
|
||||
return {
|
||||
then(resolve) {
|
||||
console.log("bar");
|
||||
resolve();
|
||||
console.log("baz");
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
a = "moo";
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "foo";
|
||||
(async function() {
|
||||
try {
|
||||
return {
|
||||
then(resolve) {
|
||||
console.log("bar");
|
||||
resolve();
|
||||
console.log("baz");
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
a = "moo";
|
||||
}
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: [
|
||||
"moo",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5692_1: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(async function() {
|
||||
(async function() {
|
||||
for await (var k of []);
|
||||
})();
|
||||
console.log("foo");
|
||||
})();
|
||||
console.log("bar");
|
||||
}
|
||||
expect: {
|
||||
(async function() {
|
||||
(async function() {
|
||||
for await (var k of []);
|
||||
})();
|
||||
console.log("foo");
|
||||
})();
|
||||
console.log("bar");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_5692_2: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(async function() {
|
||||
(async function() {
|
||||
for (var k of []);
|
||||
})();
|
||||
console.log("foo");
|
||||
})();
|
||||
console.log("bar");
|
||||
}
|
||||
expect: {
|
||||
(async function() {
|
||||
for (var k of []);
|
||||
console.log("foo");
|
||||
})();
|
||||
console.log("bar");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5791: {
|
||||
options = {
|
||||
awaits: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(async function() {
|
||||
async function f() {
|
||||
try {
|
||||
await {
|
||||
then(resolve) {
|
||||
setImmediate(() => {
|
||||
console.log("foo");
|
||||
resolve();
|
||||
});
|
||||
},
|
||||
};
|
||||
} catch (e) {
|
||||
console.log("FAIL", e);
|
||||
}
|
||||
}
|
||||
async function g() {
|
||||
try {
|
||||
await f();
|
||||
} catch (e) {}
|
||||
}
|
||||
await g();
|
||||
console.log("bar");
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(async function() {
|
||||
await async function() {
|
||||
try {
|
||||
await async function() {
|
||||
try {
|
||||
await {
|
||||
then(resolve) {
|
||||
setImmediate(() => {
|
||||
console.log("foo");
|
||||
resolve();
|
||||
});
|
||||
},
|
||||
};
|
||||
} catch (e) {
|
||||
console.log("FAIL", e);
|
||||
}
|
||||
}();
|
||||
} catch (e) {}
|
||||
}();
|
||||
console.log("bar");
|
||||
})();
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
@@ -90,3 +90,17 @@ issue_4801: {
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=10.4.0"
|
||||
}
|
||||
|
||||
issue_5728: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
console.log("" + 4n + 2);
|
||||
}
|
||||
expect: {
|
||||
console.log("42");
|
||||
}
|
||||
expect_stdout: "42"
|
||||
node_version: ">=10.4.0"
|
||||
}
|
||||
|
||||
@@ -47,3 +47,45 @@ keep_some_blocks: {
|
||||
} else stuff();
|
||||
}
|
||||
}
|
||||
|
||||
issue_1666: {
|
||||
input: {
|
||||
var a = 42;
|
||||
{
|
||||
function a() {}
|
||||
a();
|
||||
}
|
||||
console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
var a = 42;
|
||||
{
|
||||
function a() {}
|
||||
a();
|
||||
}
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1666_strict: {
|
||||
input: {
|
||||
"use strict";
|
||||
var a = 42;
|
||||
{
|
||||
function a() {}
|
||||
a();
|
||||
}
|
||||
console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var a = 42;
|
||||
{
|
||||
function a() {}
|
||||
a();
|
||||
}
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
@@ -80,6 +80,25 @@ de_morgan_1c: {
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
de_morgan_1d: {
|
||||
options = {
|
||||
booleans: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
return (a = false) || a;
|
||||
}
|
||||
console.log(f(null), f(42));
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
return a = !1;
|
||||
}
|
||||
console.log(f(null), f(42));
|
||||
}
|
||||
expect_stdout: "false false"
|
||||
}
|
||||
|
||||
de_morgan_2a: {
|
||||
options = {
|
||||
booleans: true,
|
||||
@@ -181,6 +200,31 @@ de_morgan_2d: {
|
||||
]
|
||||
}
|
||||
|
||||
de_morgan_2e: {
|
||||
options = {
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b) {
|
||||
return (a && b) && b;
|
||||
}
|
||||
console.log(f(null), f(null, {}));
|
||||
console.log(f(42), f(42, {}));
|
||||
}
|
||||
expect: {
|
||||
function f(a, b) {
|
||||
return a && b;
|
||||
}
|
||||
console.log(f(null), f(null, {}));
|
||||
console.log(f(42), f(42, {}));
|
||||
}
|
||||
expect_stdout: [
|
||||
"null null",
|
||||
"undefined {}",
|
||||
]
|
||||
}
|
||||
|
||||
de_morgan_3a: {
|
||||
options = {
|
||||
booleans: true,
|
||||
@@ -786,3 +830,37 @@ issue_5469: {
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
issue_5694_1: {
|
||||
options = {
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
var Infinity;
|
||||
// Node.js v0.12~6 (vm): 42
|
||||
console.log((Infinity = 42) && Infinity);
|
||||
}
|
||||
expect: {
|
||||
var Infinity;
|
||||
console.log((Infinity = 42) && Infinity);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_5694_2: {
|
||||
options = {
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
var undefined;
|
||||
// Node.js v0.12~6 (vm): NaN
|
||||
console.log(("foo", ++undefined) || undefined);
|
||||
}
|
||||
expect: {
|
||||
var undefined;
|
||||
console.log(("foo", ++undefined) || undefined);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
@@ -241,6 +241,94 @@ class_super: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
static_newline_1: {
|
||||
input: {
|
||||
class A {
|
||||
static
|
||||
P
|
||||
}
|
||||
console.log("P" in A, "static" in A);
|
||||
console.log("P" in new A(), "static" in new A());
|
||||
}
|
||||
expect_exact: 'class A{static P}console.log("P"in A,"static"in A);console.log("P"in new A,"static"in new A);'
|
||||
expect_stdout: [
|
||||
"true false",
|
||||
"false false",
|
||||
]
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
static_newline_2: {
|
||||
input: {
|
||||
class A {
|
||||
static
|
||||
static
|
||||
P
|
||||
}
|
||||
console.log("P" in A, "static" in A);
|
||||
console.log("P" in new A(), "static" in new A());
|
||||
}
|
||||
expect_exact: 'class A{static static;P}console.log("P"in A,"static"in A);console.log("P"in new A,"static"in new A);'
|
||||
expect_stdout: [
|
||||
"false true",
|
||||
"true false",
|
||||
]
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
static_newline_3: {
|
||||
input: {
|
||||
class A {
|
||||
static
|
||||
static
|
||||
static
|
||||
P
|
||||
}
|
||||
console.log("P" in A, "static" in A);
|
||||
console.log("P" in new A(), "static" in new A());
|
||||
}
|
||||
expect_exact: 'class A{static static;static P}console.log("P"in A,"static"in A);console.log("P"in new A,"static"in new A);'
|
||||
expect_stdout: [
|
||||
"true true",
|
||||
"false false",
|
||||
]
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
static_newline_4: {
|
||||
input: {
|
||||
class A {
|
||||
static
|
||||
static
|
||||
static
|
||||
static
|
||||
P
|
||||
}
|
||||
console.log("P" in A, "static" in A);
|
||||
console.log("P" in new A(), "static" in new A());
|
||||
}
|
||||
expect_exact: 'class A{static static;static static;P}console.log("P"in A,"static"in A);console.log("P"in new A,"static"in new A);'
|
||||
expect_stdout: [
|
||||
"false true",
|
||||
"true false",
|
||||
]
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
static_newline_init: {
|
||||
input: {
|
||||
class A {
|
||||
static
|
||||
{
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
}
|
||||
expect_exact: 'class A{static{console.log("PASS")}}'
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=16"
|
||||
}
|
||||
|
||||
static_init: {
|
||||
input: {
|
||||
var a = "foo";
|
||||
@@ -511,6 +599,7 @@ drop_extends: {
|
||||
inline: true,
|
||||
passes: 2,
|
||||
pure_getters: "strict",
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
@@ -658,6 +747,56 @@ separate_name: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
static_getter: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
(class {
|
||||
static get p() {
|
||||
console.log("PASS");
|
||||
};
|
||||
}).p;
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
(class {
|
||||
static get p() {
|
||||
console.log("PASS");
|
||||
};
|
||||
}).p;
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
static_setter: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
(class {
|
||||
static set p(v) {
|
||||
console.log(v);
|
||||
};
|
||||
}).p = "PASS";
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
(class {
|
||||
static set p(v) {
|
||||
console.log(v);
|
||||
};
|
||||
}).p = "PASS";
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
static_side_effects: {
|
||||
options = {
|
||||
inline: true,
|
||||
@@ -783,6 +922,7 @@ single_use_3: {
|
||||
|
||||
single_use_4: {
|
||||
options = {
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
@@ -1025,9 +1165,9 @@ collapse_rhs_static: {
|
||||
"use strict";
|
||||
var a = "FAIL";
|
||||
class A {
|
||||
static p = a = "PASS";
|
||||
static p = "PASS";
|
||||
}
|
||||
console.log(a);
|
||||
console.log(a = "PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=12"
|
||||
@@ -1365,6 +1505,218 @@ keep_instanceof_3: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
keep_field_reference_1: {
|
||||
options = {
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function f() {}
|
||||
class A {
|
||||
p = f;
|
||||
}
|
||||
console.log(new A().p === new A().p ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function f() {}
|
||||
class A {
|
||||
p = f;
|
||||
}
|
||||
console.log(new A().p === new A().p ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
keep_field_reference_2: {
|
||||
options = {
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function f() {}
|
||||
var A = class {
|
||||
p = f;
|
||||
};
|
||||
console.log(new A().p === new A().p ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function f() {}
|
||||
var A = class {
|
||||
p = f;
|
||||
};
|
||||
console.log(new A().p === new A().p ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
keep_field_reference_3: {
|
||||
options = {
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
class A {}
|
||||
class B {
|
||||
p = A;
|
||||
}
|
||||
console.log(new B().p === new B().p ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
class A {}
|
||||
class B {
|
||||
p = A;
|
||||
}
|
||||
console.log(new B().p === new B().p ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
keep_field_reference_4: {
|
||||
options = {
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var A = class {};
|
||||
var B = class {
|
||||
p = A;
|
||||
};
|
||||
console.log(new B().p === new B().p ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var A = class {};
|
||||
var B = class {
|
||||
p = A;
|
||||
};
|
||||
console.log(new B().p === new B().p ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
keep_static_field_reference_1: {
|
||||
options = {
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function f() {}
|
||||
class A {
|
||||
static P = f;
|
||||
}
|
||||
console.log(A.P === A.P ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
class A {
|
||||
static P = function() {};
|
||||
}
|
||||
console.log(A.P === A.P ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
keep_static_field_reference_2: {
|
||||
options = {
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function f() {}
|
||||
var A = class {
|
||||
static P = f;
|
||||
};
|
||||
console.log(A.P === A.P ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var A = class {
|
||||
static P = function() {};
|
||||
};
|
||||
console.log(A.P === A.P ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
keep_static_field_reference_3: {
|
||||
options = {
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
class A {}
|
||||
class B {
|
||||
static P = A;
|
||||
}
|
||||
console.log(B.P === B.P ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
class B {
|
||||
static P = class {};
|
||||
}
|
||||
console.log(B.P === B.P ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
keep_static_field_reference_4: {
|
||||
options = {
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var A = class {};
|
||||
var B = class {
|
||||
static P = A;
|
||||
};
|
||||
console.log(B.P === B.P ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var B = class {
|
||||
static P = class {};
|
||||
};
|
||||
console.log(B.P === B.P ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
issue_805_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
@@ -2026,6 +2378,7 @@ issue_4829_2: {
|
||||
mangle_properties: {
|
||||
mangle = {
|
||||
properties: {
|
||||
domprops: true,
|
||||
keep_quoted: true,
|
||||
},
|
||||
}
|
||||
@@ -2062,6 +2415,14 @@ mangle_properties: {
|
||||
console.log(A.s, new A().e);
|
||||
}
|
||||
expect_stdout: "PASS 42"
|
||||
expect_warnings: [
|
||||
"INFO: Preserving reserved property q",
|
||||
"INFO: Mapping property #P to #t",
|
||||
"INFO: Mapping property Q to s",
|
||||
"INFO: Mapping property #p to #i",
|
||||
"INFO: Mapping property r to e",
|
||||
"INFO: Preserving reserved property log",
|
||||
]
|
||||
node_version: ">=14.6"
|
||||
}
|
||||
|
||||
@@ -2166,6 +2527,7 @@ issue_4962_1: {
|
||||
options = {
|
||||
ie: true,
|
||||
inline: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
@@ -2197,6 +2559,7 @@ issue_4962_1_strict: {
|
||||
options = {
|
||||
ie: true,
|
||||
inline: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
@@ -2224,6 +2587,7 @@ issue_4962_1_strict_direct: {
|
||||
options = {
|
||||
ie: true,
|
||||
inline: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
@@ -2255,6 +2619,7 @@ issue_4962_2: {
|
||||
options = {
|
||||
ie: true,
|
||||
inline: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
@@ -2286,6 +2651,7 @@ issue_4962_2_strict: {
|
||||
options = {
|
||||
ie: true,
|
||||
inline: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
@@ -2314,6 +2680,7 @@ issue_4962_2_strict_direct: {
|
||||
options = {
|
||||
ie: true,
|
||||
inline: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
@@ -2348,6 +2715,7 @@ issue_4962_2_strict_direct_inline: {
|
||||
ie: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
@@ -2731,6 +3099,7 @@ issue_5053_4: {
|
||||
issue_5082_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
@@ -2763,6 +3132,7 @@ issue_5082_1: {
|
||||
issue_5082_1_strict: {
|
||||
options = {
|
||||
inline: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
@@ -2796,6 +3166,7 @@ issue_5082_2: {
|
||||
options = {
|
||||
inline: true,
|
||||
passes: 2,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
@@ -2829,6 +3200,7 @@ issue_5082_2_static: {
|
||||
options = {
|
||||
inline: true,
|
||||
passes: 2,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
@@ -3330,3 +3702,331 @@ issue_5512: {
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=16"
|
||||
}
|
||||
|
||||
issue_5531_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
class A {
|
||||
p = function() {
|
||||
var a = function f() {
|
||||
if (!a)
|
||||
console.log("foo");
|
||||
return 42;
|
||||
}(a++);
|
||||
}();
|
||||
}
|
||||
new A();
|
||||
new A();
|
||||
}
|
||||
expect: {
|
||||
class A {
|
||||
p = function() {
|
||||
var a = function f() {
|
||||
if (!a)
|
||||
console.log("foo");
|
||||
return 42;
|
||||
}(a++);
|
||||
}();
|
||||
}
|
||||
new A();
|
||||
new A();
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"foo",
|
||||
]
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
issue_5531_2: {
|
||||
options = {
|
||||
inline: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
class A {
|
||||
static p = function() {
|
||||
var a = function f() {
|
||||
if (!a)
|
||||
console.log("foo");
|
||||
return 42;
|
||||
}(a++);
|
||||
}();
|
||||
}
|
||||
new A();
|
||||
new A();
|
||||
}
|
||||
expect: {
|
||||
class A {
|
||||
static p = (a = function f() {
|
||||
if (!a)
|
||||
console.log("foo");
|
||||
return 42;
|
||||
}(a++), void 0);
|
||||
}
|
||||
var a;
|
||||
new A();
|
||||
new A();
|
||||
}
|
||||
expect_stdout: "foo"
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
issue_5531_3: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
class A {
|
||||
static {
|
||||
(function() {
|
||||
var a = function f() {
|
||||
if (!a)
|
||||
console.log("foo");
|
||||
return 42;
|
||||
}(a++);
|
||||
})();
|
||||
}
|
||||
}
|
||||
new A();
|
||||
new A();
|
||||
}
|
||||
expect: {
|
||||
class A {
|
||||
static {
|
||||
a = function f() {
|
||||
if (!a)
|
||||
console.log("foo");
|
||||
return 42;
|
||||
}(a++),
|
||||
void 0;
|
||||
var a;
|
||||
}
|
||||
}
|
||||
new A();
|
||||
new A();
|
||||
}
|
||||
expect_stdout: "foo"
|
||||
node_version: ">=16"
|
||||
}
|
||||
|
||||
issue_5662: {
|
||||
options = {
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(new (function() {
|
||||
var g = function(a) {
|
||||
return a;
|
||||
};
|
||||
return class {
|
||||
h(b) {
|
||||
return g(b);
|
||||
}
|
||||
};
|
||||
}())().h("PASS"));
|
||||
}
|
||||
expect: {
|
||||
console.log(new (function() {
|
||||
var g = function(a) {
|
||||
return a;
|
||||
};
|
||||
return class {
|
||||
h(b) {
|
||||
return g(b);
|
||||
}
|
||||
};
|
||||
}())().h("PASS"));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5682_class_key: {
|
||||
mangle = {
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
return "foo" in a;
|
||||
}
|
||||
class A {
|
||||
foo() {}
|
||||
}
|
||||
console.log(f(new A()) ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function f(o) {
|
||||
return "o" in o;
|
||||
}
|
||||
class A {
|
||||
o() {}
|
||||
}
|
||||
console.log(f(new A()) ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5682_class_key_computed: {
|
||||
mangle = {
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
return "foo" in a;
|
||||
}
|
||||
class A {
|
||||
["foo"]() {}
|
||||
}
|
||||
console.log(f(new A()) ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function f(o) {
|
||||
return "o" in o;
|
||||
}
|
||||
class A {
|
||||
["o"]() {}
|
||||
}
|
||||
console.log(f(new A()) ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5724: {
|
||||
options = {
|
||||
arrows: true,
|
||||
inline: true,
|
||||
keep_fargs: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
class A {
|
||||
static P = function(a) {
|
||||
console.log(a, a);
|
||||
}(a);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
(function(a) {
|
||||
console.log(a, a);
|
||||
})(a);
|
||||
}
|
||||
expect_stdout: ReferenceError("a is not defined")
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
issue_5735_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
console.log(typeof function(a) {
|
||||
return class {
|
||||
static P = { ...a };
|
||||
};
|
||||
}([ 42..p ] = []));
|
||||
}
|
||||
expect: {
|
||||
console.log(typeof function(a) {
|
||||
return class {
|
||||
static P = { ...a };
|
||||
};
|
||||
}([ 42..p ] = []));
|
||||
}
|
||||
expect_stdout: "function"
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
issue_5735_2: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
console.log(typeof function(a) {
|
||||
return class {
|
||||
p = a;
|
||||
};
|
||||
}(console.log("PASS")));
|
||||
}
|
||||
expect: {
|
||||
console.log(typeof function(a) {
|
||||
return class {
|
||||
p = a;
|
||||
};
|
||||
}(console.log("PASS")));
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"function",
|
||||
]
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
issue_5747_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
(async function() {
|
||||
var a = await 42;
|
||||
class A {
|
||||
static P = a && console.log(typeof this);
|
||||
}
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
(async function() {
|
||||
var a = await 42;
|
||||
class A {
|
||||
static P = a && console.log(typeof this);
|
||||
}
|
||||
})();
|
||||
}
|
||||
expect_stdout: "function"
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
issue_5747_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
(async function() {
|
||||
var a = await 42;
|
||||
class A {
|
||||
static {
|
||||
a && console.log(typeof this);
|
||||
}
|
||||
}
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
(async function() {
|
||||
var a = await 42;
|
||||
class A {
|
||||
static {
|
||||
a && console.log(typeof this);
|
||||
}
|
||||
}
|
||||
})();
|
||||
}
|
||||
expect_stdout: "function"
|
||||
node_version: ">=16"
|
||||
}
|
||||
|
||||
@@ -4996,7 +4996,7 @@ cascade_forin: {
|
||||
]
|
||||
}
|
||||
|
||||
unsafe_builtin: {
|
||||
unsafe_builtin_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: "strict",
|
||||
@@ -5020,6 +5020,46 @@ unsafe_builtin: {
|
||||
expect_stdout: "1 4"
|
||||
}
|
||||
|
||||
unsafe_builtin_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
toplevel: true,
|
||||
unsafe: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
A = "PASS";
|
||||
var a = A;
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
console.log(A = "PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
unsafe_builtin_3: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unsafe: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
A = "PASS";
|
||||
(function() {
|
||||
var a = A;
|
||||
console.log(a);
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
A = "PASS";
|
||||
(function() {
|
||||
console.log(A);
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
return_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
@@ -7350,30 +7390,39 @@ substitution_assign: {
|
||||
b = 1 + (b = a);
|
||||
console.log(a, b);
|
||||
}
|
||||
function f4(a, b) {
|
||||
b = 1 + (a = b);
|
||||
console.log(a, b);
|
||||
}
|
||||
f1(42, "foo");
|
||||
f2(42, "foo");
|
||||
f3(42, "foo");
|
||||
f4("bar", 41);
|
||||
}
|
||||
expect: {
|
||||
function f1(a, b) {
|
||||
console.log(f1 = a, a);
|
||||
}
|
||||
function f2(a, b) {
|
||||
a = 1 + (b = a);
|
||||
console.log(a, b);
|
||||
console.log(a = 1 + (b = a), b);
|
||||
}
|
||||
function f3(a, b) {
|
||||
b = 1 + (b = a);
|
||||
console.log(a, b = 1 + (b = a));
|
||||
}
|
||||
function f4(a, b) {
|
||||
b = 1 + (a = b);
|
||||
console.log(a, b);
|
||||
}
|
||||
f1(42, "foo");
|
||||
f2(42, "foo");
|
||||
f3(42, "foo");
|
||||
f4("bar", 41);
|
||||
}
|
||||
expect_stdout: [
|
||||
"42 42",
|
||||
"43 42",
|
||||
"42 43",
|
||||
"41 42",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -9321,12 +9370,11 @@ issue_4874: {
|
||||
})(a = 42);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
null;
|
||||
(function(b) {
|
||||
for (var c in a && a[console.log("PASS")])
|
||||
for (var c in 42, 42[console.log("PASS")])
|
||||
console;
|
||||
})(a = 42);
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
@@ -9865,7 +9913,8 @@ issue_5276: {
|
||||
}
|
||||
expect: {
|
||||
var a = A = "PASS";
|
||||
a.p = a.p + null - 42;
|
||||
a.p += null;
|
||||
a.p -= 42;
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
@@ -9979,3 +10028,332 @@ issue_5396: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5568: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
A = "FAIL";
|
||||
var a = (A = "PASS", !1);
|
||||
for (var b in a);
|
||||
console.log(A);
|
||||
}
|
||||
expect: {
|
||||
A = "FAIL";
|
||||
for (var b in !(A = "PASS"));
|
||||
console.log(A);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5638_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
console;
|
||||
a = [ 42 ];
|
||||
console || FAIL(a);
|
||||
console.log(a++);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
console;
|
||||
a = [ 42 ];
|
||||
console || FAIL(a);
|
||||
console.log(a++);
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
issue_5638_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
console;
|
||||
a = [ 6 ];
|
||||
console || FAIL(a);
|
||||
console.log(a *= 7);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
console;
|
||||
a = [ 6 ];
|
||||
console || FAIL(a);
|
||||
console.log(a *= 7);
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
issue_5638_3: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var log = console.log;
|
||||
var a = { foo: 42 }, b;
|
||||
for (var k in a) {
|
||||
b = a[k];
|
||||
log(k || b, b++);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var log = console.log;
|
||||
var a = { foo: 42 }, b;
|
||||
for (var k in a) {
|
||||
b = a[k];
|
||||
log(k || b, b++);
|
||||
}
|
||||
}
|
||||
expect_stdout: "foo 42"
|
||||
}
|
||||
|
||||
issue_5638_4: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var log = console.log;
|
||||
var a = { foo: 6 }, b;
|
||||
for (var k in a) {
|
||||
b = a[k];
|
||||
log(k || b, b *= 7);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var log = console.log;
|
||||
var a = { foo: 6 }, b;
|
||||
for (var k in a) {
|
||||
b = a[k];
|
||||
log(k || b, b *= 7);
|
||||
}
|
||||
}
|
||||
expect_stdout: "foo 42"
|
||||
}
|
||||
|
||||
issue_5643: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = 3, b;
|
||||
a *= 7;
|
||||
b = !!this;
|
||||
console || console.log(b);
|
||||
console.log(a * ++b);
|
||||
}
|
||||
expect: {
|
||||
var a = 3, b;
|
||||
a *= 7;
|
||||
b = !!this;
|
||||
console || console.log(b);
|
||||
console.log(a * ++b);
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
issue_5719: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = 42, b;
|
||||
switch (b = a) {
|
||||
case a:
|
||||
case b:
|
||||
case a++:
|
||||
}
|
||||
console.log(a === b++ ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
var a = 42, b;
|
||||
switch (b = a) {
|
||||
case a:
|
||||
case b:
|
||||
case a++:
|
||||
}
|
||||
console.log(a === b++ ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5779: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = A = "foo";
|
||||
a.p = 42;
|
||||
if (a && !a.p)
|
||||
console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
var a = A = "foo";
|
||||
a.p = 42;
|
||||
if (a, !a.p)
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_1666: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
var x = 42;
|
||||
{
|
||||
x();
|
||||
function x() {
|
||||
console.log("foo");
|
||||
}
|
||||
}
|
||||
console.log(typeof x);
|
||||
}
|
||||
expect: {
|
||||
var x = 42;
|
||||
{
|
||||
x();
|
||||
function x() {
|
||||
console.log("foo");
|
||||
}
|
||||
}
|
||||
console.log(typeof x);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1666_strict: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var x = 42;
|
||||
{
|
||||
x();
|
||||
function x() {
|
||||
console.log("foo");
|
||||
}
|
||||
}
|
||||
console.log(typeof x);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var x = 42;
|
||||
{
|
||||
x();
|
||||
function x() {
|
||||
console.log("foo");
|
||||
}
|
||||
}
|
||||
console.log(typeof x);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1666_undefined: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
var undefined = 42;
|
||||
{
|
||||
undefined();
|
||||
function undefined() {
|
||||
console.log("foo");
|
||||
}
|
||||
}
|
||||
console.log(typeof undefined);
|
||||
}
|
||||
expect: {
|
||||
var undefined = 42;
|
||||
{
|
||||
undefined();
|
||||
function undefined() {
|
||||
console.log("foo");
|
||||
}
|
||||
}
|
||||
console.log(typeof undefined);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1666_undefined_strict: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var undefined = 42;
|
||||
{
|
||||
undefined();
|
||||
function undefined() {
|
||||
console.log("foo");
|
||||
}
|
||||
}
|
||||
console.log(typeof undefined);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var undefined = 42;
|
||||
{
|
||||
undefined();
|
||||
function undefined() {
|
||||
console.log("foo");
|
||||
}
|
||||
}
|
||||
console.log(typeof undefined);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_5869: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a, b, log = console.log;
|
||||
log();
|
||||
a.p = 0;
|
||||
b = a;
|
||||
log(b);
|
||||
}
|
||||
expect: {
|
||||
var a, log = console.log;
|
||||
log();
|
||||
log(void (a.p = 0));
|
||||
}
|
||||
expect_stdout: TypeError("Cannot set properties of undefined")
|
||||
}
|
||||
|
||||
@@ -275,6 +275,7 @@ issue_2857_3: {
|
||||
issue_2857_4: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, p) {
|
||||
@@ -305,6 +306,7 @@ issue_2857_4: {
|
||||
issue_2857_5: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, p) {
|
||||
@@ -528,6 +530,7 @@ nullish_assign: {
|
||||
nullish_chain: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
|
||||
@@ -12,7 +12,7 @@ concat_1: {
|
||||
|
||||
var e = 1 + x() + 2 + "X" + 3 + "boo";
|
||||
|
||||
// be careful with concatentation with "\0" with octal-looking strings.
|
||||
// be careful with concatenation with "\0" with octal-looking strings.
|
||||
var f = "\0" + 360 + "\0" + 8 + "\0";
|
||||
}
|
||||
expect: {
|
||||
@@ -273,6 +273,23 @@ concat_9: {
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
concat_sequence: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
strings: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
console.log(12 + (a = null, "34" + a));
|
||||
}
|
||||
expect: {
|
||||
console.log(12 + "34" + null);
|
||||
}
|
||||
expect_stdout: "1234null"
|
||||
}
|
||||
|
||||
issue_3689: {
|
||||
options = {
|
||||
strings: true,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -142,6 +142,80 @@ if_dead_branch: {
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
retain_tail_1: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
var b = "foo";
|
||||
if (a) {
|
||||
const b = "bar";
|
||||
while (console.log("baz"));
|
||||
console.log(b);
|
||||
} else {
|
||||
while (console.log("moo"));
|
||||
console.log(b);
|
||||
}
|
||||
}
|
||||
f();
|
||||
f(42);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
var b = "foo";
|
||||
if (a) {
|
||||
const b = "bar";
|
||||
while (console.log("baz"));
|
||||
console.log(b);
|
||||
} else {
|
||||
while (console.log("moo"));
|
||||
console.log(b);
|
||||
}
|
||||
}
|
||||
f();
|
||||
f(42);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
retain_tail_2: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
var b = "foo";
|
||||
if (a) {
|
||||
while (console.log("bar"));
|
||||
console.log(b);
|
||||
} else {
|
||||
const b = "baz";
|
||||
while (console.log("moo"));
|
||||
console.log(b);
|
||||
}
|
||||
}
|
||||
f();
|
||||
f(42);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
var b = "foo";
|
||||
if (a) {
|
||||
while (console.log("bar"));
|
||||
console.log(b);
|
||||
} else {
|
||||
const b = "baz";
|
||||
while (console.log("moo"));
|
||||
console.log(b);
|
||||
}
|
||||
}
|
||||
f();
|
||||
f(42);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
merge_vars_1: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
@@ -579,6 +653,37 @@ dead_block_after_return: {
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
if_return_3: {
|
||||
options = {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
function f(b) {
|
||||
if (console) {
|
||||
const b = a;
|
||||
return b;
|
||||
} else
|
||||
while (console.log("FAIL 1"));
|
||||
return b;
|
||||
}
|
||||
console.log(f("FAIL 2"));
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
function f(b) {
|
||||
if (console) {
|
||||
const b = a;
|
||||
return b;
|
||||
} else
|
||||
while (console.log("FAIL 1"));
|
||||
return b;
|
||||
}
|
||||
console.log(f("FAIL 2"));
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
do_if_continue_1: {
|
||||
options = {
|
||||
if_return: true,
|
||||
@@ -1872,3 +1977,257 @@ issue_5476: {
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
issue_5516: {
|
||||
options = {
|
||||
inline: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(typeof function() {
|
||||
try {} catch (a) {
|
||||
(function f() {
|
||||
a;
|
||||
})();
|
||||
}
|
||||
{
|
||||
const a = function() {};
|
||||
return a;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(typeof function() {
|
||||
try {} catch (a) {
|
||||
void a;
|
||||
}
|
||||
{
|
||||
const a = function() {};
|
||||
return a;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
issue_5580_1: {
|
||||
mangle = {}
|
||||
input: {
|
||||
"use strict";
|
||||
console.log(function(a, b, c) {
|
||||
try {
|
||||
FAIL;
|
||||
} catch (e) {
|
||||
return function() {
|
||||
var d = e, i, j;
|
||||
{
|
||||
const e = j;
|
||||
}
|
||||
return a;
|
||||
}();
|
||||
} finally {
|
||||
const e = 42;
|
||||
}
|
||||
}("PASS"));
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log(function(r, n, t) {
|
||||
try {
|
||||
FAIL;
|
||||
} catch (o) {
|
||||
return function() {
|
||||
var n = o, t, c;
|
||||
{
|
||||
const o = c;
|
||||
}
|
||||
return r;
|
||||
}();
|
||||
} finally {
|
||||
const c = 42;
|
||||
}
|
||||
}("PASS"));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5580_2: {
|
||||
options = {
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
varify: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
(function() {
|
||||
try {
|
||||
throw "PASS";
|
||||
} catch (e) {
|
||||
return function() {
|
||||
console.log(e);
|
||||
{
|
||||
const e = "FAIL 1";
|
||||
}
|
||||
}();
|
||||
} finally {
|
||||
const e = "FAIL 2";
|
||||
}
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
(function() {
|
||||
try {
|
||||
throw "PASS";
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
{
|
||||
const e = "FAIL 1";
|
||||
}
|
||||
return;
|
||||
} finally {
|
||||
var e = "FAIL 2";
|
||||
}
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5591: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
switch (console.log("foo")) {
|
||||
case console.log("bar"):
|
||||
if (console.log("baz"))
|
||||
return;
|
||||
else {
|
||||
const a = 42;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case null:
|
||||
FAIL;
|
||||
}
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
switch (console.log("foo")) {
|
||||
case console.log("bar"):
|
||||
if (console.log("baz"))
|
||||
return;
|
||||
else {
|
||||
const a = 42;
|
||||
return;
|
||||
}
|
||||
case null:
|
||||
FAIL;
|
||||
}
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5656: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
merge_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
var b = a;
|
||||
b++;
|
||||
{
|
||||
const a = b;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a) {
|
||||
var b = a;
|
||||
{
|
||||
const a = ++b;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_5660: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
try {
|
||||
a;
|
||||
var b;
|
||||
return b;
|
||||
} catch (e) {
|
||||
var a = "FAIL";
|
||||
const b = null;
|
||||
return a;
|
||||
}
|
||||
}
|
||||
console.log(f());
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
try {
|
||||
var b;
|
||||
return b;
|
||||
} catch (e) {
|
||||
var a = "FAIL";
|
||||
const b = null;
|
||||
return a;
|
||||
}
|
||||
}
|
||||
console.log(f());
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_5787: {
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
const a = 42;
|
||||
switch (a) {
|
||||
case 42:
|
||||
const a = "PASS";
|
||||
return a;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
const a = 42;
|
||||
switch (a) {
|
||||
case 42:
|
||||
const a = "PASS";
|
||||
return a;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
@@ -1485,8 +1485,6 @@ self_assignments_5: {
|
||||
}
|
||||
expect: {
|
||||
var i = 0, l = [ "FAIL", "PASS" ];
|
||||
l[0];
|
||||
l[0];
|
||||
l[0] = l[1];
|
||||
console.log(l[0], 2);
|
||||
}
|
||||
@@ -1707,3 +1705,28 @@ issue_5506: {
|
||||
"bar",
|
||||
]
|
||||
}
|
||||
|
||||
issue_5641: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
if (a || b) {
|
||||
var b = "PASS", c = b && console.log(b);
|
||||
} else
|
||||
var d = a || b;
|
||||
}
|
||||
f(42);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
var b, c, d;
|
||||
(a || b) && (b = "PASS") && console.log(b);
|
||||
}
|
||||
f(42);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -180,6 +180,26 @@ collapse_arg_sequence: {
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
collapse_in_arg: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
keep_fargs: false,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(a, b = a) {
|
||||
b("PASS");
|
||||
})(console.log);
|
||||
}
|
||||
expect: {
|
||||
(function(a) {
|
||||
a("PASS");
|
||||
})(console.log);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
collapse_value_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
@@ -541,7 +561,7 @@ inline_side_effects_2: {
|
||||
}
|
||||
expect: {
|
||||
var a = 42;
|
||||
[ [].e = --a ] = [ console ];
|
||||
[ [][0] = --a ] = [ console ];
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "42"
|
||||
@@ -648,6 +668,8 @@ drop_fargs: {
|
||||
hoist_vars: {
|
||||
options = {
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
@@ -655,8 +677,7 @@ hoist_vars: {
|
||||
console.log(a, b);
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
var [ b = 42 ] = [];
|
||||
var a = "PASS", [ b = 42 ] = [];
|
||||
console.log(a, b);
|
||||
}
|
||||
expect_stdout: "PASS 42"
|
||||
@@ -1170,6 +1191,49 @@ mangle_arrow_2_toplevel: {
|
||||
node_version: ">=6.9.3"
|
||||
}
|
||||
|
||||
collapse_preceding_simple_arg: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = "foo";
|
||||
console.log(function(b, c = "bar") {
|
||||
return b + c;
|
||||
}(a, a));
|
||||
}
|
||||
expect: {
|
||||
var a = "foo";
|
||||
console.log(function(b, c = "bar") {
|
||||
return a + c;
|
||||
}(0, a));
|
||||
}
|
||||
expect_stdout: "foofoo"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
drop_preceding_simple_arg: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
keep_fargs: false,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = "foo";
|
||||
console.log(function(b, c = "bar") {
|
||||
return b + c;
|
||||
}(a, a));
|
||||
}
|
||||
expect: {
|
||||
var a = "foo";
|
||||
console.log(function(c = "bar") {
|
||||
return a + c;
|
||||
}(a));
|
||||
}
|
||||
expect_stdout: "foofoo"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_4444: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
@@ -1558,7 +1622,7 @@ issue_4502_4: {
|
||||
(function(a, b = console.log("FAIL")) {})(..."" + console.log(42));
|
||||
}
|
||||
expect: {
|
||||
[ , [].e = console.log("FAIL") ] = [ ..."" + console.log(42) ];
|
||||
[ , [][0] = console.log("FAIL") ] = [ ..."" + console.log(42) ];
|
||||
}
|
||||
expect_stdout: "42"
|
||||
node_version: ">=6"
|
||||
@@ -1655,7 +1719,7 @@ issue_4540: {
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_4548: {
|
||||
issue_4548_1: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
toplevel: true,
|
||||
@@ -1681,6 +1745,32 @@ issue_4548: {
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_4548_2: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
A = "foo";
|
||||
var a = A;
|
||||
var [ b = c = "bar" ] = [ console, console.log(a) ];
|
||||
console.log(c);
|
||||
var c;
|
||||
}
|
||||
expect: {
|
||||
A = "foo";
|
||||
var a = A;
|
||||
var [ b = c = "bar" ] = [ console, console.log(a) ];
|
||||
console.log(c);
|
||||
var c;
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"undefined",
|
||||
]
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_4588_1_unused: {
|
||||
options = {
|
||||
unused: true,
|
||||
@@ -2023,7 +2113,7 @@ issue_5246_1: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
expect_warnings: [
|
||||
"INFO: Dropping unused default argument {}=42 [test/compress/default-values.js:1,29]",
|
||||
"INFO: Dropping unused default argument {} [test/compress/default-values.js:1,29]",
|
||||
]
|
||||
node_version: ">=6"
|
||||
}
|
||||
@@ -2183,7 +2273,7 @@ issue_5340_2: {
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
[ [].e = 0 ] = [ ({ p: a } = true).q ];
|
||||
[ [][0] = 0 ] = [ ({ p: a } = true).q ];
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
@@ -2203,7 +2293,7 @@ issue_5340_3: {
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
(function() {})(a = true["p"]);
|
||||
(function() {})(a = true.p);
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
@@ -2415,7 +2505,7 @@ issue_5463: {
|
||||
var a, b, b;
|
||||
console.log("PASS") && (
|
||||
b = a = void 0,
|
||||
b = [a = FAIL] = a && a
|
||||
b = [a = FAIL] = a
|
||||
);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
@@ -2462,3 +2552,586 @@ issue_5485: {
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_1_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(b = 42) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_1_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(b = 42) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_2_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f([ b ] = []) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;) {
|
||||
var [ [] = [] ] = [];
|
||||
throw "PASS";
|
||||
}
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_2_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f([ b ] = []) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;) {
|
||||
var [ [ , ] = [] ] = [];
|
||||
throw "PASS";
|
||||
}
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_3_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(b = 42, c = null) {
|
||||
c;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_3_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(b = 42, c = null) {
|
||||
c;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_4_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(b = 42, [ c ] = []) {
|
||||
c;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;) {
|
||||
var [ [] = [] ] = [];
|
||||
throw "PASS";
|
||||
}
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_4_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(b = 42, [ c ] = []) {
|
||||
c;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;) {
|
||||
var [ [] = [] ] = [];
|
||||
throw "PASS";
|
||||
}
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5536: {
|
||||
options = {
|
||||
inline: true,
|
||||
keep_fargs: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function*() {
|
||||
(([], a = 42) => {})([]);
|
||||
console.log(typeof a);
|
||||
})().next();
|
||||
}
|
||||
expect: {
|
||||
(function*() {
|
||||
[ , [][0] = 0 ] = [ [] ],
|
||||
void 0;
|
||||
console.log(typeof a);
|
||||
})().next();
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5566_1: {
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(a, f = function() {
|
||||
return a;
|
||||
}) {
|
||||
var a = "foo";
|
||||
console.log(a, f());
|
||||
})("bar");
|
||||
}
|
||||
expect: {
|
||||
(function(a, f = function() {
|
||||
return a;
|
||||
}) {
|
||||
var a = "foo";
|
||||
console.log(a, f());
|
||||
})("bar");
|
||||
}
|
||||
expect_stdout: "foo bar"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5566_2: {
|
||||
options = {
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
(function(a, f = function() {
|
||||
return a;
|
||||
}) {
|
||||
function a() {}
|
||||
console.log(typeof a, typeof f());
|
||||
})(42);
|
||||
}
|
||||
expect: {
|
||||
(function(a, f = function() {
|
||||
return a;
|
||||
}) {
|
||||
function a() {}
|
||||
console.log(typeof a, typeof f());
|
||||
})(42);
|
||||
}
|
||||
expect_stdout: "function number"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5566_3: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(a, f = function() {
|
||||
return a;
|
||||
}) {
|
||||
function a() {}
|
||||
console.log(typeof a, typeof f());
|
||||
})(42);
|
||||
}
|
||||
expect: {
|
||||
(function(a, f = function() {
|
||||
return a;
|
||||
}) {
|
||||
function a() {}
|
||||
console.log(typeof a, typeof f());
|
||||
})(42);
|
||||
}
|
||||
expect_stdout: "function number"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5566_4: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(a, b = function() {
|
||||
return a;
|
||||
}) {
|
||||
var a = 0;
|
||||
b()("PASS");
|
||||
})(console.log);
|
||||
}
|
||||
expect: {
|
||||
(function(a, b = function() {
|
||||
return a;
|
||||
}) {
|
||||
var a = 0;
|
||||
b()("PASS");
|
||||
})(console.log);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5566_5: {
|
||||
options = {
|
||||
hoist_vars: true,
|
||||
}
|
||||
input: {
|
||||
(function(a, f = function() {
|
||||
return a;
|
||||
}) {
|
||||
var a = "foo";
|
||||
var b;
|
||||
console.log(a, f());
|
||||
})("bar");
|
||||
}
|
||||
expect: {
|
||||
(function(a, f = function() {
|
||||
return a;
|
||||
}) {
|
||||
var a, b;
|
||||
a = "foo";
|
||||
console.log(a, f());
|
||||
})("bar");
|
||||
}
|
||||
expect_stdout: "foo bar"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5651: {
|
||||
options = {
|
||||
ie: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function arguments(a = "FAIL") {
|
||||
try {} catch (arguments) {
|
||||
var arguments;
|
||||
}
|
||||
return arguments[0];
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function arguments(a = "FAIL") {
|
||||
try {} catch (arguments) {
|
||||
var arguments;
|
||||
}
|
||||
return arguments[0];
|
||||
}());
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5774: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
while (console.log("PASS")) {
|
||||
if (console) {
|
||||
a = void 0;
|
||||
var b = void 0;
|
||||
var c = void 0;
|
||||
([ a = 0 ] = [ b, b ]);
|
||||
var a;
|
||||
}
|
||||
}
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
while (console.log("PASS")) {
|
||||
var a, b, c, a;
|
||||
console && (
|
||||
c = b = a = void 0,
|
||||
[ a = 0 ] = [ a, a ]
|
||||
);
|
||||
}
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5863: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
hoist_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(typeof function f(a = function() {
|
||||
f = 42;
|
||||
return f;
|
||||
}()) {
|
||||
var f;
|
||||
var f;
|
||||
return a;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(typeof function f(a = function() {
|
||||
f = 42;
|
||||
return f;
|
||||
}()) {
|
||||
var f;
|
||||
return a;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "function"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
@@ -472,6 +472,93 @@ funarg_collapse_vars_3: {
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
funarg_collapse_vars_4: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
(function(b, { log: c }) {
|
||||
c(b);
|
||||
})(a, console);
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
(function(b, { log: c }) {
|
||||
c(a);
|
||||
})(0, console);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
funarg_collapse_vars_5: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
A = "FAIL";
|
||||
B = "PASS";
|
||||
try {
|
||||
console.log(function({}, a) {
|
||||
return a;
|
||||
}(null, A = B));
|
||||
} catch (e) {}
|
||||
console.log(A);
|
||||
}
|
||||
expect: {
|
||||
A = "FAIL";
|
||||
B = "PASS";
|
||||
try {
|
||||
console.log(function({}, a) {
|
||||
return a;
|
||||
}(null, A = B));
|
||||
} catch (e) {}
|
||||
console.log(A);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
funarg_collapse_vars_6: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
A = "FAIL";
|
||||
B = "PASS";
|
||||
function f() {
|
||||
console.log(function({}, a) {
|
||||
return a;
|
||||
}(null, A = B));
|
||||
}
|
||||
try {
|
||||
f();
|
||||
} catch (e) {
|
||||
console.log(A);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
A = "FAIL";
|
||||
B = "PASS";
|
||||
function f() {
|
||||
console.log(function({}, a) {
|
||||
return a;
|
||||
}(null, A = B));
|
||||
}
|
||||
try {
|
||||
f();
|
||||
} catch (e) {
|
||||
console.log(A);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
funarg_reduce_vars_1: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
@@ -1219,7 +1306,7 @@ keep_reference: {
|
||||
}
|
||||
expect: {
|
||||
var a = [ {}, 42 ];
|
||||
var [ b ] = a;
|
||||
var b = a[0];
|
||||
console.log(a[0] === b ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
@@ -1252,7 +1339,7 @@ maintain_position_var: {
|
||||
}
|
||||
expect: {
|
||||
A = "FAIL";
|
||||
var [ , b ] = [ A ];
|
||||
var b = [ A ][1];
|
||||
console.log(b || "PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
@@ -1295,7 +1382,7 @@ side_effects_object: {
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var a = null, c = (console, 42["c"]);
|
||||
var a = null, c = (console, 42..c);
|
||||
try {
|
||||
c[a = "PASS"];
|
||||
} catch (e) {
|
||||
@@ -1565,6 +1652,8 @@ fn_name_unused: {
|
||||
hoist_vars: {
|
||||
options = {
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
@@ -1572,8 +1661,7 @@ hoist_vars: {
|
||||
console.log(a, b);
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
var [ b ] = [ 42 ];
|
||||
var a = "PASS", b = [ 42 ][0];
|
||||
console.log(a, b);
|
||||
}
|
||||
expect_stdout: "PASS 42"
|
||||
@@ -1596,7 +1684,7 @@ singleton_1: {
|
||||
expect: {
|
||||
var b, a = "P"[0], o = {};
|
||||
o.p = [ "FAIL"["1"] ][0];
|
||||
o.q = { foo: "S"[0] }["foo"];
|
||||
o.q = { foo: "S"[0] }.foo;
|
||||
[ b = "S" ] = [];
|
||||
console.log(a + o.p + o.q + b);
|
||||
}
|
||||
@@ -1649,6 +1737,23 @@ singleton_side_effects: {
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
mangle_properties: {
|
||||
mangle = {
|
||||
properties: {
|
||||
domprops: true,
|
||||
},
|
||||
}
|
||||
input: {
|
||||
function f({ p: a }) {
|
||||
return a;
|
||||
}
|
||||
console.log(f({ p: "PASS" }));
|
||||
}
|
||||
expect_exact: 'function f({n}){return n}console.log(f({n:"PASS"}));'
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_4280: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
@@ -1815,8 +1920,8 @@ issue_4288: {
|
||||
console.log(typeof b);
|
||||
}()]: a,
|
||||
}) {
|
||||
var b = a;
|
||||
b++;
|
||||
var a = a;
|
||||
a++;
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
@@ -1989,17 +2094,16 @@ issue_4312: {
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
b = "PASS",
|
||||
c = "FAIL",
|
||||
[
|
||||
{
|
||||
[a = b]: d,
|
||||
[c = b]: d,
|
||||
},
|
||||
] = [ c && c ],
|
||||
void 0;
|
||||
var b, c, d;
|
||||
console.log(a);
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
@@ -3497,7 +3601,7 @@ issue_5314_2: {
|
||||
A = this;
|
||||
new function() {
|
||||
[ {
|
||||
[console.log(this === A ? "FAIL" : "PASS")]: [].e,
|
||||
[console.log(this === A ? "FAIL" : "PASS")]: [][0],
|
||||
} ] = [ 42 ];
|
||||
}();
|
||||
}
|
||||
@@ -3646,3 +3750,494 @@ issue_5485: {
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f([ b ]) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})([]);
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f([ b ]) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})([]);
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5573: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
var log = console.log;
|
||||
var a = "FAIL";
|
||||
(function([ { [log(a)]: b } ]) {
|
||||
A = 42;
|
||||
})((a = "PASS", [ {} ]));
|
||||
log(a, A);
|
||||
}
|
||||
expect: {
|
||||
var log = console.log;
|
||||
var a = "FAIL";
|
||||
(function([ { [log(a)]: b } ]) {
|
||||
A = 42;
|
||||
})((a = "PASS", [ {} ]));
|
||||
log(a, A);
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"PASS 42",
|
||||
]
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5651: {
|
||||
options = {
|
||||
ie: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function arguments({}) {
|
||||
try {} catch (arguments) {
|
||||
var arguments;
|
||||
}
|
||||
return arguments[0];
|
||||
}("PASS"));
|
||||
}
|
||||
expect: {
|
||||
console.log(function arguments({}) {
|
||||
try {} catch (arguments) {
|
||||
var arguments;
|
||||
}
|
||||
return arguments[0];
|
||||
}("PASS"));
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5843_1: {
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var { p: a } = {
|
||||
__proto__: {
|
||||
p: "PASS",
|
||||
},
|
||||
};
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = {
|
||||
__proto__: {
|
||||
p: "PASS",
|
||||
},
|
||||
}.p;
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5843_2: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
({ p: a } = {
|
||||
__proto__: {
|
||||
p: "PASS",
|
||||
},
|
||||
});
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
a = {
|
||||
__proto__: {
|
||||
p: "PASS",
|
||||
},
|
||||
}.p;
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5844: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
(function(a) {
|
||||
[ a.p ] = 42;
|
||||
})(console.log("PASS"));
|
||||
} catch (e) {}
|
||||
}
|
||||
expect: {
|
||||
try {
|
||||
(function(a) {
|
||||
[ a.p ] = 42;
|
||||
})(console.log("PASS"));
|
||||
} catch (e) {}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5854_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
var b = a;
|
||||
a++;
|
||||
[ b[0] ] = [ "foo" ];
|
||||
return a;
|
||||
}([]) ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a) {
|
||||
var b = a;
|
||||
a++;
|
||||
[ b[0] ] = [ "foo" ];
|
||||
return a;
|
||||
}([]) ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5854_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
var b = a;
|
||||
a++;
|
||||
({ p: b[0] } = { p: "foo" });
|
||||
return a;
|
||||
}([]) ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a) {
|
||||
var b = a;
|
||||
a++;
|
||||
({ p: b[0] } = { p: "foo" });
|
||||
return a;
|
||||
}([]) ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5866_1: {
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = {};
|
||||
var { p: { q: b } } = {
|
||||
p: a,
|
||||
r: a.q = "PASS",
|
||||
};
|
||||
console.log(b);
|
||||
}
|
||||
expect: {
|
||||
var a = {};
|
||||
var { q: b } = {
|
||||
p: a,
|
||||
r: a.q = "PASS",
|
||||
}.p;
|
||||
console.log(b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5866_2: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = {}, b;
|
||||
({ p: { q: b } } = {
|
||||
p: a,
|
||||
r: a.q = "PASS",
|
||||
});
|
||||
console.log(b);
|
||||
}
|
||||
expect: {
|
||||
var b, a = {};
|
||||
({ q: b } = {
|
||||
p: a,
|
||||
r: a.q = "PASS",
|
||||
}.p);
|
||||
console.log(b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5866_3: {
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = {};
|
||||
var [ { p: b } ] = [ a, a.p = "PASS" ];
|
||||
console.log(b);
|
||||
}
|
||||
expect: {
|
||||
var a = {};
|
||||
var { p: b } = [ a, a.p = "PASS" ][0];
|
||||
console.log(b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5866_4: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = {}, b;
|
||||
[ { p: b } ] = [ a, a.p = "PASS" ];
|
||||
console.log(b);
|
||||
}
|
||||
expect: {
|
||||
var b, a = {};
|
||||
({ p: b } = [ a, a.p = "PASS" ][0]);
|
||||
console.log(b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5866_5: {
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = [];
|
||||
var [ [ b ] ] = [ a, a[0] = "PASS" ];
|
||||
console.log(b);
|
||||
}
|
||||
expect: {
|
||||
var a = [];
|
||||
var [ b ] = [ a, a[0] = "PASS" ][0];
|
||||
console.log(b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5866_6: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = [], b;
|
||||
[ [ b ] ] = [ a, a[0] = "PASS" ];
|
||||
console.log(b);
|
||||
}
|
||||
expect: {
|
||||
var b, a = [];
|
||||
[ b ] = [ a, a[0] = "PASS" ][0];
|
||||
console.log(b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5866_7: {
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = {};
|
||||
var [ { p: b }, c ] = [ a, a.p = {} ];
|
||||
console.log(b === c ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
var a = {};
|
||||
var [ { p: b }, c ] = [ a, a.p = {} ];
|
||||
console.log(b === c ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5866_8: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = {}, b, c;
|
||||
[ { p: b }, c ] = [ a, a.p = {} ];
|
||||
console.log(b === c ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
var b, c, a = {};
|
||||
[ { p: b }, c ] = [ a, a.p = {} ];
|
||||
console.log(b === c ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5866_9: {
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = {};
|
||||
var [ b, { p: c } ] = [ a.p = {}, a ];
|
||||
console.log(b === c ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
var a = {};
|
||||
var [ b, c ] = [ a.p = {}, a.p ];
|
||||
console.log(b === c ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5866_10: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = {}, b, c;
|
||||
[ b, { p: c } ] = [ a.p = {}, a ];
|
||||
console.log(b === c ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
var b, c, a = {};
|
||||
[ b, c ] = [ a.p = {}, a.p ];
|
||||
console.log(b === c ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5866_11: {
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = {};
|
||||
var { p: { q: b } } = { p: a = { q: {} } };
|
||||
console.log(a.q === b ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
var a = {};
|
||||
var b = { p: (a = { q: {} }).q }.p;
|
||||
console.log(a.q === b ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5866_12: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = {}, b;
|
||||
({ p: { q: b } } = { p: a = { q: {} } });
|
||||
console.log(a.q === b ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
var b, a = {};
|
||||
b = { p: (a = { q: {} }).q }.p;
|
||||
console.log(a.q === b ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
@@ -131,19 +131,34 @@ valid_after_invalid_2: {
|
||||
}
|
||||
|
||||
issue_5368_1: {
|
||||
expression = true
|
||||
options = {
|
||||
directives: true,
|
||||
expression: true,
|
||||
}
|
||||
input: {
|
||||
"foo";
|
||||
}
|
||||
expect: {
|
||||
"foo";
|
||||
"foo"
|
||||
}
|
||||
expect_exact: '"foo"'
|
||||
expect_stdout: "foo"
|
||||
}
|
||||
|
||||
issue_5368_2: {
|
||||
expression = true
|
||||
options = {
|
||||
directives: true,
|
||||
expression: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
"foo";
|
||||
})()
|
||||
}
|
||||
expect_exact: "function(){}()"
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
issue_5368_3: {
|
||||
options = {
|
||||
directives: true,
|
||||
expression: true,
|
||||
|
||||
@@ -409,6 +409,15 @@ drop_toplevel_retain: {
|
||||
a = 2;
|
||||
console.log(3);
|
||||
}
|
||||
expect_stdout: "3"
|
||||
expect_warnings: [
|
||||
"INFO: Retaining variable a",
|
||||
"INFO: Retaining variable f",
|
||||
"INFO: Dropping unused variable b [test/compress/drop-unused.js:1,15]",
|
||||
"INFO: Dropping unused variable c [test/compress/drop-unused.js:1,22]",
|
||||
"INFO: Dropping unused function g [test/compress/drop-unused.js:8,17]",
|
||||
"WARN: Dropping unused function h [test/compress/drop-unused.js:9,17]",
|
||||
]
|
||||
}
|
||||
|
||||
drop_toplevel_retain_array: {
|
||||
@@ -442,6 +451,15 @@ drop_toplevel_retain_array: {
|
||||
a = 2;
|
||||
console.log(3);
|
||||
}
|
||||
expect_stdout: "3"
|
||||
expect_warnings: [
|
||||
"INFO: Retaining variable a",
|
||||
"INFO: Retaining variable f",
|
||||
"INFO: Dropping unused variable b [test/compress/drop-unused.js:1,15]",
|
||||
"INFO: Dropping unused variable c [test/compress/drop-unused.js:1,22]",
|
||||
"INFO: Dropping unused function g [test/compress/drop-unused.js:8,17]",
|
||||
"WARN: Dropping unused function h [test/compress/drop-unused.js:9,17]",
|
||||
]
|
||||
}
|
||||
|
||||
drop_toplevel_retain_regex: {
|
||||
@@ -471,6 +489,15 @@ drop_toplevel_retain_regex: {
|
||||
a = 2;
|
||||
console.log(3);
|
||||
}
|
||||
expect_stdout: "3"
|
||||
expect_warnings: [
|
||||
"INFO: Retaining variable a",
|
||||
"INFO: Retaining variable f",
|
||||
"INFO: Dropping unused variable b [test/compress/drop-unused.js:1,15]",
|
||||
"INFO: Dropping unused variable c [test/compress/drop-unused.js:1,22]",
|
||||
"INFO: Dropping unused function g [test/compress/drop-unused.js:8,17]",
|
||||
"WARN: Dropping unused function h [test/compress/drop-unused.js:9,17]",
|
||||
]
|
||||
}
|
||||
|
||||
drop_toplevel_all_retain: {
|
||||
@@ -501,6 +528,15 @@ drop_toplevel_all_retain: {
|
||||
a = 2;
|
||||
console.log(3);
|
||||
}
|
||||
expect_stdout: "3"
|
||||
expect_warnings: [
|
||||
"INFO: Retaining variable a",
|
||||
"INFO: Retaining variable f",
|
||||
"INFO: Dropping unused variable b [test/compress/drop-unused.js:1,15]",
|
||||
"INFO: Dropping unused variable c [test/compress/drop-unused.js:1,22]",
|
||||
"INFO: Dropping unused function g [test/compress/drop-unused.js:8,17]",
|
||||
"WARN: Dropping unused function h [test/compress/drop-unused.js:9,17]",
|
||||
]
|
||||
}
|
||||
|
||||
drop_toplevel_funcs_retain: {
|
||||
@@ -532,6 +568,12 @@ drop_toplevel_funcs_retain: {
|
||||
function g() {}
|
||||
console.log(b = 3);
|
||||
}
|
||||
expect_stdout: "3"
|
||||
expect_warnings: [
|
||||
"INFO: Retaining variable a",
|
||||
"INFO: Retaining variable f",
|
||||
"WARN: Dropping unused function h [test/compress/drop-unused.js:9,17]",
|
||||
]
|
||||
}
|
||||
|
||||
drop_toplevel_vars_retain: {
|
||||
@@ -564,6 +606,13 @@ drop_toplevel_vars_retain: {
|
||||
function h() {}
|
||||
console.log(3);
|
||||
}
|
||||
expect_stdout: "3"
|
||||
expect_warnings: [
|
||||
"INFO: Retaining variable a",
|
||||
"INFO: Retaining variable f",
|
||||
"INFO: Dropping unused variable b [test/compress/drop-unused.js:1,15]",
|
||||
"INFO: Dropping unused variable c [test/compress/drop-unused.js:1,22]",
|
||||
]
|
||||
}
|
||||
|
||||
drop_toplevel_keep_assign: {
|
||||
@@ -1829,7 +1878,7 @@ issue_2846: {
|
||||
var c = function(a, b) {
|
||||
a = 0;
|
||||
b && b(a);
|
||||
return a++;
|
||||
return +a;
|
||||
}();
|
||||
console.log(c);
|
||||
}
|
||||
@@ -2927,14 +2976,12 @@ issue_4025: {
|
||||
console.log(a, b, d);
|
||||
}
|
||||
expect: {
|
||||
var c = 0;
|
||||
try {
|
||||
console.log(c);
|
||||
console.log(0);
|
||||
} finally {
|
||||
var d = c + 1;
|
||||
c = 0;
|
||||
0;
|
||||
}
|
||||
console.log(1, 1, d);
|
||||
console.log(1, 1, 1);
|
||||
}
|
||||
expect_stdout: [
|
||||
"0",
|
||||
@@ -3647,7 +3694,7 @@ issue_5224: {
|
||||
(function() {
|
||||
var a = "FAIL 1";
|
||||
null;
|
||||
a = console.log(a);
|
||||
console.log(a);
|
||||
})(function() {
|
||||
console.log(1 / 0);
|
||||
a;
|
||||
@@ -3685,3 +3732,85 @@ issue_5271: {
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
issue_5533_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(b) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5533_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(b) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -3390,3 +3390,29 @@ issue_5380: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5558: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = 99, b = 0;
|
||||
a++;
|
||||
b++;
|
||||
b += a;
|
||||
b *= a;
|
||||
b += a;
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = 99, b = 0;
|
||||
b++,
|
||||
b = (b += ++a) * a + a,
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "100"
|
||||
}
|
||||
|
||||
@@ -109,6 +109,17 @@ foreign: {
|
||||
expect_exact: 'export*from"foo";export{}from"bar";export*as a from"baz";export{default}from"moo";export{b,c as case,default as delete,d}from"moz";'
|
||||
}
|
||||
|
||||
non_identifiers: {
|
||||
beautify = {
|
||||
quote_style: 3,
|
||||
}
|
||||
input: {
|
||||
export * as "42" from 'foo';
|
||||
export { '42', "delete" as 'foo' } from "bar";
|
||||
}
|
||||
expect_exact: "export*as\"42\"from'foo';export{'42',delete as foo}from\"bar\";"
|
||||
}
|
||||
|
||||
same_quotes: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
@@ -249,7 +260,7 @@ hoist_exports_2: {
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
let e, a = 42["foo"];
|
||||
let e, a = 42..foo;
|
||||
function f(t, { [e]: o }) {
|
||||
t(o, f);
|
||||
}
|
||||
@@ -549,3 +560,23 @@ issue_5444: {
|
||||
export var a = console;
|
||||
}
|
||||
}
|
||||
|
||||
issue_5628: {
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
export default function f() {
|
||||
for (a in 42);
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
export default function f() {
|
||||
for (a in 42);
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -629,7 +629,7 @@ inline_binary_and: {
|
||||
return void "moo";
|
||||
return;
|
||||
} else
|
||||
return;
|
||||
return void 0;
|
||||
}());
|
||||
}
|
||||
expect_stdout: [
|
||||
@@ -5512,6 +5512,40 @@ substitute_use_strict: {
|
||||
]
|
||||
}
|
||||
|
||||
substitute_assignment: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
properties: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b, c) {
|
||||
a[b] = c;
|
||||
}
|
||||
var o = {};
|
||||
f(o, 42, null);
|
||||
f(o, "foo", "bar");
|
||||
for (var k in o)
|
||||
console.log(k, o[k]);
|
||||
}
|
||||
expect: {
|
||||
var o = {};
|
||||
o[42] = null;
|
||||
o.foo = "bar";
|
||||
for (var k in o)
|
||||
console.log(k, o[k]);
|
||||
}
|
||||
expect_stdout: [
|
||||
"42 null",
|
||||
"foo bar",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3833_1: {
|
||||
options = {
|
||||
inline: 3,
|
||||
@@ -5582,7 +5616,7 @@ issue_3835: {
|
||||
return f();
|
||||
})();
|
||||
}
|
||||
expect_stdout: true
|
||||
expect_stdout: RangeError("Maximum call stack size exceeded")
|
||||
}
|
||||
|
||||
issue_3836_1: {
|
||||
@@ -7835,7 +7869,7 @@ issue_5249_1: {
|
||||
while (console.log("FAIL 2"));
|
||||
return;
|
||||
} else
|
||||
return;
|
||||
return void 0;
|
||||
throw "FAIL 3";
|
||||
}());
|
||||
}
|
||||
@@ -8629,6 +8663,7 @@ module_inline: {
|
||||
inline: true,
|
||||
module: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = f;
|
||||
@@ -8646,3 +8681,293 @@ module_inline: {
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
single_use_inline_collision: {
|
||||
options = {
|
||||
inline: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
(function() {
|
||||
var f = function() {
|
||||
while (console.log(a));
|
||||
};
|
||||
(function() {
|
||||
(function() {
|
||||
f();
|
||||
})();
|
||||
(function(a) {
|
||||
a || a("FAIL");
|
||||
})(console.log);
|
||||
})();
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
(function() {
|
||||
(function() {
|
||||
while (console.log(a));
|
||||
return;
|
||||
})();
|
||||
(function(a) {
|
||||
a || a("FAIL");
|
||||
})(console.log);
|
||||
return;
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5692: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
while (console.log("PASS"))
|
||||
if (console)
|
||||
return;
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
while (console.log("PASS"))
|
||||
if (console)
|
||||
return;
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5766_1: {
|
||||
options = {
|
||||
booleans: true,
|
||||
evaluate: true,
|
||||
functions: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
log = function(a) {
|
||||
console.log(typeof a);
|
||||
};
|
||||
do {
|
||||
(function() {
|
||||
try {
|
||||
var f = function() {};
|
||||
log(f && f);
|
||||
} catch (e) {}
|
||||
})();
|
||||
} while (0);
|
||||
}
|
||||
expect: {
|
||||
log = function(a) {
|
||||
console.log(typeof a);
|
||||
};
|
||||
do {
|
||||
try {
|
||||
function f() {}
|
||||
log(f);
|
||||
} catch (e) {}
|
||||
} while (0);
|
||||
}
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
issue_5766_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
functions: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
log = function(a) {
|
||||
console.log(typeof a);
|
||||
};
|
||||
do {
|
||||
(function() {
|
||||
try {
|
||||
var f = function() {};
|
||||
log(f && f);
|
||||
} catch (e) {}
|
||||
})();
|
||||
} while (0);
|
||||
}
|
||||
expect: {
|
||||
log = function(a) {
|
||||
console.log(typeof a);
|
||||
};
|
||||
do {
|
||||
try {
|
||||
function f() {}
|
||||
log(f);
|
||||
} catch (e) {}
|
||||
} while (0);
|
||||
}
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
issue_5841_1: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
passes: 2,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 42;
|
||||
(function() {
|
||||
f();
|
||||
var b = f();
|
||||
function f() {
|
||||
if (console && a)
|
||||
g && g();
|
||||
}
|
||||
function g() {
|
||||
var c;
|
||||
for (;console.log("foo"););
|
||||
(function h(d) {
|
||||
d && d.p;
|
||||
})();
|
||||
}
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
var a = 42;
|
||||
(function() {
|
||||
f();
|
||||
f();
|
||||
function f() {
|
||||
{
|
||||
if (console && a) {
|
||||
for (;console.log("foo"););
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
})();
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"foo",
|
||||
]
|
||||
}
|
||||
|
||||
issue_5841_2: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
if_return: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
passes: 2,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 42;
|
||||
(function() {
|
||||
f();
|
||||
var b = f();
|
||||
function f() {
|
||||
if (console && a)
|
||||
g && g();
|
||||
}
|
||||
function g() {
|
||||
var c;
|
||||
for (;console.log("foo"););
|
||||
(function h(d) {
|
||||
d && d.p;
|
||||
})();
|
||||
}
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
var a = 42;
|
||||
(function() {
|
||||
f();
|
||||
f();
|
||||
function f() {
|
||||
if (console && a)
|
||||
for (;console.log("foo"););
|
||||
}
|
||||
})();
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"foo",
|
||||
]
|
||||
}
|
||||
|
||||
issue_5851_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
console.log("PASS") && f();
|
||||
function f() {
|
||||
return f();
|
||||
}
|
||||
f;
|
||||
}
|
||||
expect: {
|
||||
console.log("PASS") && f();
|
||||
function f() {
|
||||
return f();
|
||||
}
|
||||
f;
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5851_2: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = f();
|
||||
f();
|
||||
function f() {
|
||||
if (console.log("foo"))
|
||||
console && f();
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
f();
|
||||
f();
|
||||
function f() {
|
||||
console.log("foo") && console && f();
|
||||
}
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"foo",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -462,6 +462,11 @@ issue_2473_1: {
|
||||
var x = {};
|
||||
var y = [];
|
||||
}
|
||||
expect_warnings: [
|
||||
"INFO: Retaining variable x",
|
||||
"INFO: Retaining variable y",
|
||||
"WARN: Dropping unused variable z [test/compress/hoist_props.js:3,12]",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2473_2: {
|
||||
@@ -484,6 +489,11 @@ issue_2473_2: {
|
||||
var x = {};
|
||||
var y = [];
|
||||
}
|
||||
expect_warnings: [
|
||||
"INFO: Retaining variable x",
|
||||
"INFO: Retaining variable y",
|
||||
"WARN: Dropping unused variable z [test/compress/hoist_props.js:3,12]",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2473_3: {
|
||||
@@ -509,6 +519,9 @@ issue_2473_3: {
|
||||
console.log(o.a, o.b);
|
||||
}
|
||||
expect_stdout: "1 2"
|
||||
expect_warnings: [
|
||||
"INFO: Retaining variable o",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2473_4: {
|
||||
@@ -535,6 +548,9 @@ issue_2473_4: {
|
||||
})();
|
||||
}
|
||||
expect_stdout: "1 2"
|
||||
expect_warnings: [
|
||||
"INFO: Dropping unused variable o [test/compress/hoist_props.js:2,16]",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2508_1: {
|
||||
|
||||
@@ -2,6 +2,8 @@ statements: {
|
||||
options = {
|
||||
hoist_funs: false,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
@@ -25,6 +27,8 @@ statements_funs: {
|
||||
options = {
|
||||
hoist_funs: true,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
@@ -48,6 +52,8 @@ sequences: {
|
||||
options = {
|
||||
hoist_funs: false,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
@@ -71,6 +77,8 @@ sequences_funs: {
|
||||
options = {
|
||||
hoist_funs: true,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
@@ -108,7 +116,8 @@ catch_var: {
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
a = "PASS";
|
||||
var a;
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
@@ -118,6 +127,8 @@ issue_2295: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function foo(o) {
|
||||
@@ -139,6 +150,7 @@ issue_4487_1: {
|
||||
options = {
|
||||
functions: true,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
keep_fnames: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
@@ -163,6 +175,7 @@ issue_4487_2: {
|
||||
options = {
|
||||
functions: true,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
keep_fnames: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
@@ -188,6 +201,7 @@ issue_4487_3: {
|
||||
options = {
|
||||
functions: true,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
keep_fnames: true,
|
||||
passes: 3,
|
||||
reduce_vars: true,
|
||||
@@ -214,6 +228,7 @@ issue_4489: {
|
||||
evaluate: true,
|
||||
hoist_vars: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
@@ -248,8 +263,7 @@ issue_4517: {
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
var a = 2;
|
||||
return (A = a) + typeof !1;
|
||||
return (A = 2) + typeof !1;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "2boolean"
|
||||
@@ -260,6 +274,7 @@ issue_4736: {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
merge_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
@@ -279,7 +294,7 @@ issue_4736: {
|
||||
expect: {
|
||||
(function() {
|
||||
(function() {
|
||||
0,
|
||||
0;
|
||||
console.log(1 << 30);
|
||||
})();
|
||||
})();
|
||||
@@ -291,6 +306,7 @@ issue_4839: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
@@ -317,6 +333,7 @@ issue_4859: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
keep_infinity: true,
|
||||
merge_vars: true,
|
||||
reduce_vars: true,
|
||||
@@ -347,6 +364,7 @@ issue_4893_1: {
|
||||
evaluate: true,
|
||||
hoist_vars: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
@@ -367,9 +385,8 @@ issue_4893_1: {
|
||||
}
|
||||
expect: {
|
||||
try{
|
||||
(function f() {
|
||||
(function() {
|
||||
null.p += 42;
|
||||
f;
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
@@ -406,9 +423,7 @@ issue_4893_2: {
|
||||
expect: {
|
||||
try{
|
||||
(function() {
|
||||
var a;
|
||||
a = null;
|
||||
a.p += 42;
|
||||
null.p += 42;
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
@@ -441,7 +456,7 @@ issue_4898: {
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5187: {
|
||||
issue_5187_1: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
hoist_vars: true,
|
||||
@@ -459,6 +474,37 @@ issue_5187: {
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
var a, b;
|
||||
a = 42;
|
||||
do {
|
||||
b = { 0: a++ };
|
||||
} while (console.log(b[b ^= 0]));
|
||||
})();
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
issue_5187_2: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
var a = 42;
|
||||
do {
|
||||
var b = { 0: a++ };
|
||||
} while (console.log(b[b ^= 0]));
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
var b, a = 42;
|
||||
@@ -547,9 +593,9 @@ issue_5411_1: {
|
||||
console.log(b);
|
||||
}
|
||||
expect: {
|
||||
var b, c, a = "PASS";
|
||||
var a, b, c;
|
||||
b++;
|
||||
b = a;
|
||||
b = a = "PASS";
|
||||
c = c && c[b];
|
||||
console.log(b);
|
||||
}
|
||||
@@ -563,6 +609,7 @@ issue_5411_2: {
|
||||
evaluate: true,
|
||||
hoist_vars: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
@@ -575,9 +622,9 @@ issue_5411_2: {
|
||||
}
|
||||
expect: {
|
||||
var b, c;
|
||||
b++;
|
||||
b++,
|
||||
b = "PASS",
|
||||
c = c && c[b];
|
||||
c,
|
||||
console.log(b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
@@ -596,6 +643,30 @@ issue_5411_3: {
|
||||
var a = A = a;
|
||||
console.log(A);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
a = console;
|
||||
a = A = ++a;
|
||||
console.log(A);
|
||||
}
|
||||
expect_stdout: "NaN"
|
||||
}
|
||||
|
||||
issue_5411_4: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = console;
|
||||
a++;
|
||||
var a = A = a;
|
||||
console.log(A);
|
||||
}
|
||||
expect: {
|
||||
var a = console;
|
||||
a = A = ++a;
|
||||
@@ -603,3 +674,130 @@ issue_5411_3: {
|
||||
}
|
||||
expect_stdout: "NaN"
|
||||
}
|
||||
|
||||
issue_5626: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
hoist_vars: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = function() {
|
||||
return console.log(arguments[0]), 42;
|
||||
}("PASS") ? null : "foo";
|
||||
for (var b in a)
|
||||
FAIL;
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
console.log(arguments[0]);
|
||||
}("PASS"));
|
||||
for (var b in null)
|
||||
FAIL;
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5638_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
hoist_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL";
|
||||
var a = [ 42 ];
|
||||
console || FAIL(a);
|
||||
console.log(a++);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
a = "FAIL";
|
||||
a = [ 42 ];
|
||||
console || FAIL(a);
|
||||
console.log(a++);
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
issue_5638_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
hoist_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL";
|
||||
var a = [ 6 ];
|
||||
console || FAIL(a);
|
||||
console.log(a *= 7);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
a = "FAIL";
|
||||
a = [ 6 ];
|
||||
console || FAIL(a);
|
||||
console.log(a *= 7);
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
issue_5638_3: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
hoist_vars: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var log = console.log;
|
||||
var o = { foo: 42 };
|
||||
for (var k in o) {
|
||||
var v = o[k];
|
||||
log(k || v, v++);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var log, o, k, v;
|
||||
log = console.log;
|
||||
for (k in o = { foo: 42 }) {
|
||||
v = o[k];
|
||||
log(k || v, v++);
|
||||
}
|
||||
}
|
||||
expect_stdout: "foo 42"
|
||||
}
|
||||
|
||||
issue_5638_4: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
hoist_vars: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var log = console.log;
|
||||
var o = { foo: 6 };
|
||||
for (var k in o) {
|
||||
var v = o[k];
|
||||
log(k || v, v *= 7);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var log, o, k, v;
|
||||
log = console.log;
|
||||
for (k in o = { foo: 6 }) {
|
||||
v = o[k];
|
||||
log(k || v, v *= 7);
|
||||
}
|
||||
}
|
||||
expect_stdout: "foo 42"
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -40,6 +40,17 @@ default_keys: {
|
||||
expect_exact: 'import foo,{bar}from"baz";'
|
||||
}
|
||||
|
||||
non_identifiers: {
|
||||
beautify = {
|
||||
quote_style: 3,
|
||||
}
|
||||
input: {
|
||||
import { '42' as foo } from "bar";
|
||||
import { "foo" as bar } from 'baz';
|
||||
}
|
||||
expect_exact: "import{'42'as foo}from\"bar\";import{foo as bar}from'baz';"
|
||||
}
|
||||
|
||||
dynamic: {
|
||||
input: {
|
||||
(async a => await import(a))("foo").then(bar);
|
||||
@@ -129,12 +140,12 @@ mangle: {
|
||||
}
|
||||
input: {
|
||||
import foo, { bar } from "baz";
|
||||
consoe.log(moo);
|
||||
console.log(moo);
|
||||
import * as moo from "moz";
|
||||
}
|
||||
expect: {
|
||||
import o, { bar as m } from "baz";
|
||||
consoe.log(r);
|
||||
console.log(r);
|
||||
import * as r from "moz";
|
||||
}
|
||||
}
|
||||
@@ -146,16 +157,44 @@ rename_mangle: {
|
||||
}
|
||||
input: {
|
||||
import foo, { bar } from "baz";
|
||||
consoe.log(moo);
|
||||
console.log(moo);
|
||||
import * as moo from "moz";
|
||||
}
|
||||
expect: {
|
||||
import o, { bar as m } from "baz";
|
||||
consoe.log(r);
|
||||
console.log(r);
|
||||
import * as r from "moz";
|
||||
}
|
||||
}
|
||||
|
||||
mangle_export_import: {
|
||||
mangle = {
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
export let o = A;
|
||||
import { p as A } from "foo";
|
||||
}
|
||||
expect: {
|
||||
export let o = p;
|
||||
import { p } from "foo";
|
||||
}
|
||||
}
|
||||
|
||||
mangle_import_export: {
|
||||
mangle = {
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
import { p as A } from "foo";
|
||||
export let o = A;
|
||||
}
|
||||
expect: {
|
||||
import { p } from "foo";
|
||||
export let o = p;
|
||||
}
|
||||
}
|
||||
|
||||
keep_ref: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
@@ -227,3 +266,33 @@ issue_4708_2: {
|
||||
import a from "foo";
|
||||
}
|
||||
}
|
||||
|
||||
pr_5550_1: {
|
||||
input: {
|
||||
if (console)
|
||||
import("foo");
|
||||
else
|
||||
import.meta.url.replace(/bar/g, console.log);
|
||||
}
|
||||
expect: {
|
||||
if (console)
|
||||
import("foo");
|
||||
else
|
||||
import.meta.url.replace(/bar/g, console.log);
|
||||
}
|
||||
}
|
||||
|
||||
pr_5550_2: {
|
||||
input: {
|
||||
L: {
|
||||
import("foo");
|
||||
import.meta.url.replace(/bar/g, console.log);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
L: {
|
||||
import("foo");
|
||||
import.meta.url.replace(/bar/g, console.log);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
issue_1321_no_debug: {
|
||||
mangle = {
|
||||
properties: {
|
||||
domprops: true,
|
||||
keep_quoted: true,
|
||||
},
|
||||
}
|
||||
@@ -23,6 +24,7 @@ issue_1321_debug: {
|
||||
mangle = {
|
||||
properties: {
|
||||
debug: "",
|
||||
domprops: true,
|
||||
keep_quoted: true,
|
||||
},
|
||||
}
|
||||
@@ -44,6 +46,7 @@ issue_1321_debug: {
|
||||
issue_1321_with_quoted: {
|
||||
mangle = {
|
||||
properties: {
|
||||
domprops: true,
|
||||
keep_quoted: false,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* There was an incorrect sort behaviour documented in issue #143:
|
||||
* There was an incorrect sort behavior documented in issue #143:
|
||||
* (x = f(…)) <= x → x >= (x = f(…))
|
||||
*
|
||||
* For example, let the equation be:
|
||||
@@ -12,37 +12,54 @@
|
||||
* a >= (a = parseInt('100')) → 99 >= 100 → false
|
||||
*/
|
||||
|
||||
tranformation_sort_order_equal: {
|
||||
transformation_sort_order_equal: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
|
||||
input: { (a = parseInt('100')) == a }
|
||||
expect: { (a = parseInt('100')) == a }
|
||||
input: {
|
||||
console.log((a = parseInt("100")) == a);
|
||||
}
|
||||
expect: {
|
||||
console.log((a = parseInt("100")) == a);
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
tranformation_sort_order_unequal: {
|
||||
transformation_sort_order_unequal: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
|
||||
input: { (a = parseInt('100')) != a }
|
||||
expect: { (a = parseInt('100')) != a }
|
||||
input: {
|
||||
console.log((a = parseInt("100")) != a);
|
||||
}
|
||||
expect: {
|
||||
console.log((a = parseInt("100")) != a);
|
||||
}
|
||||
expect_stdout: "false"
|
||||
}
|
||||
|
||||
tranformation_sort_order_lesser_or_equal: {
|
||||
transformation_sort_order_lesser_or_equal: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
|
||||
input: { (a = parseInt('100')) <= a }
|
||||
expect: { (a = parseInt('100')) <= a }
|
||||
input: {
|
||||
console.log((a = parseInt("100")) <= a);
|
||||
}
|
||||
expect: {
|
||||
console.log((a = parseInt("100")) <= a);
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
tranformation_sort_order_greater_or_equal: {
|
||||
|
||||
transformation_sort_order_greater_or_equal: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
|
||||
input: { (a = parseInt('100')) >= a }
|
||||
expect: { (a = parseInt('100')) >= a }
|
||||
}
|
||||
input: {
|
||||
console.log((a = parseInt("100")) >= a);
|
||||
}
|
||||
expect: {
|
||||
console.log((a = parseInt("100")) >= a);
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
@@ -53,11 +53,21 @@ mangle_props: {
|
||||
);
|
||||
}
|
||||
expect_stdout: "1 1 1 2 2 2 3 3 3 4 4 4 5 5"
|
||||
expect_warnings: [
|
||||
"INFO: Preserving reserved property undefined",
|
||||
"INFO: Preserving reserved property NaN",
|
||||
"INFO: Preserving reserved property Infinity",
|
||||
"INFO: Preserving reserved property -Infinity",
|
||||
"INFO: Preserving reserved property null",
|
||||
"INFO: Preserving reserved property log",
|
||||
]
|
||||
}
|
||||
|
||||
numeric_literal: {
|
||||
mangle = {
|
||||
properties: true,
|
||||
properties: {
|
||||
domprops: true,
|
||||
},
|
||||
}
|
||||
beautify = {
|
||||
beautify: true,
|
||||
@@ -106,11 +116,19 @@ numeric_literal: {
|
||||
"4 5 4 4",
|
||||
"8 7 8",
|
||||
]
|
||||
expect_warnings: [
|
||||
"INFO: Mapping property 0x25 to o",
|
||||
"INFO: Mapping property 1E42 to b",
|
||||
"INFO: Preserving reserved property log",
|
||||
]
|
||||
}
|
||||
|
||||
identifier: {
|
||||
mangle = {
|
||||
properties: true,
|
||||
properties: {
|
||||
builtins: true,
|
||||
domprops: true,
|
||||
},
|
||||
}
|
||||
input: {
|
||||
var obj = {
|
||||
@@ -209,37 +227,37 @@ identifier: {
|
||||
B: 28,
|
||||
C: 29,
|
||||
D: 30,
|
||||
F: 31,
|
||||
G: 32,
|
||||
false: 33,
|
||||
null: 34,
|
||||
true: 35,
|
||||
H: 36,
|
||||
I: 37,
|
||||
J: 38,
|
||||
K: 39,
|
||||
L: 40,
|
||||
M: 41,
|
||||
N: 42,
|
||||
O: 43,
|
||||
P: 44,
|
||||
Q: 45,
|
||||
R: 46,
|
||||
S: 47,
|
||||
T: 48,
|
||||
U: 49,
|
||||
V: 50,
|
||||
W: 51,
|
||||
X: 52,
|
||||
Y: 53,
|
||||
Z: 54,
|
||||
$: 55,
|
||||
_: 56,
|
||||
ee: 57,
|
||||
te: 58,
|
||||
ne: 59,
|
||||
ae: 60,
|
||||
ie: 61,
|
||||
E: 31,
|
||||
F: 32,
|
||||
G: 33,
|
||||
H: 34,
|
||||
I: 35,
|
||||
J: 36,
|
||||
K: 37,
|
||||
L: 38,
|
||||
M: 39,
|
||||
N: 40,
|
||||
O: 41,
|
||||
P: 42,
|
||||
Q: 43,
|
||||
R: 44,
|
||||
S: 45,
|
||||
T: 46,
|
||||
U: 47,
|
||||
V: 48,
|
||||
W: 49,
|
||||
X: 50,
|
||||
Y: 51,
|
||||
Z: 52,
|
||||
$: 53,
|
||||
_: 54,
|
||||
ee: 55,
|
||||
te: 56,
|
||||
ne: 57,
|
||||
ae: 58,
|
||||
ie: 59,
|
||||
oe: 60,
|
||||
re: 61,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,6 +108,7 @@ safe_undefined: {
|
||||
}
|
||||
|
||||
negate_iife_3: {
|
||||
expression = true
|
||||
options = {
|
||||
conditionals: true,
|
||||
expression: true,
|
||||
@@ -123,6 +124,7 @@ negate_iife_3: {
|
||||
}
|
||||
|
||||
negate_iife_3_off: {
|
||||
expression = true
|
||||
options = {
|
||||
conditionals: true,
|
||||
expression: true,
|
||||
@@ -203,6 +205,7 @@ negate_iife_5_off: {
|
||||
}
|
||||
|
||||
issue_1254_negate_iife_true: {
|
||||
expression = true
|
||||
options = {
|
||||
expression: true,
|
||||
inline: true,
|
||||
@@ -215,11 +218,12 @@ issue_1254_negate_iife_true: {
|
||||
};
|
||||
})()();
|
||||
}
|
||||
expect_exact: 'void console.log("test");'
|
||||
expect_exact: 'void console.log("test")'
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1254_negate_iife_nested: {
|
||||
expression = true
|
||||
options = {
|
||||
expression: true,
|
||||
inline: true,
|
||||
@@ -232,7 +236,7 @@ issue_1254_negate_iife_nested: {
|
||||
};
|
||||
})()()()()();
|
||||
}
|
||||
expect_exact: '(void console.log("test"))()()();'
|
||||
expect_exact: '(void console.log("test"))()()()'
|
||||
}
|
||||
|
||||
negate_iife_issue_1073: {
|
||||
|
||||
@@ -15,7 +15,7 @@ collapse: {
|
||||
var a;
|
||||
b = c();
|
||||
a = typeof b === 'function' ? b() : b;
|
||||
return 'stirng' == typeof a && d();
|
||||
return 'string' == typeof a && d();
|
||||
}
|
||||
function f3(c) {
|
||||
var a;
|
||||
@@ -41,7 +41,7 @@ collapse: {
|
||||
return void 0 !== ('function' === typeof b ? b() : b) && c();
|
||||
}
|
||||
function f2(b) {
|
||||
return 'stirng' == typeof ('function' === typeof (b = c()) ? b() : b) && d();
|
||||
return 'string' == typeof ('function' === typeof (b = c()) ? b() : b) && d();
|
||||
}
|
||||
function f3(c) {
|
||||
var a;
|
||||
|
||||
195
test/compress/issue-5614.js
Normal file
195
test/compress/issue-5614.js
Normal file
@@ -0,0 +1,195 @@
|
||||
record_update: {
|
||||
options = {
|
||||
loops: true,
|
||||
passes: 3,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var value = { a: 42, b: "PASS" };
|
||||
var unused = _Utils_update(value, { b: "FAIL" });
|
||||
function _Utils_update(oldRecord, updatedFields) {
|
||||
var newRecord = {};
|
||||
for (var key in oldRecord)
|
||||
newRecord[key] = oldRecord[key];
|
||||
for (var key in updatedFields)
|
||||
newRecord[key] = updatedFields[key];
|
||||
return newRecord;
|
||||
}
|
||||
}
|
||||
expect: {}
|
||||
}
|
||||
|
||||
currying: {
|
||||
options = {
|
||||
inline: true,
|
||||
passes: 3,
|
||||
pure_getters: "strict",
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function F(arity, fun, wrapper) {
|
||||
wrapper.a = arity;
|
||||
wrapper.f = fun;
|
||||
return wrapper;
|
||||
}
|
||||
function F2(fun) {
|
||||
return F(2, fun, function(a) {
|
||||
return function(b) {
|
||||
return fun(a, b);
|
||||
};
|
||||
});
|
||||
}
|
||||
function _Utils_eq(x, y) {
|
||||
var pair, stack = [], isEqual = _Utils_eqHelp(x, y, 0, stack);
|
||||
while (isEqual && (pair = stack.pop()))
|
||||
isEqual = _Utils_eqHelp(pair.a, pair.b, 0, stack);
|
||||
return isEqual;
|
||||
}
|
||||
var _Utils_equal = F2(_Utils_eq);
|
||||
}
|
||||
expect: {}
|
||||
}
|
||||
|
||||
conditional_property_write: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
var o = {};
|
||||
if (a)
|
||||
o.p = console.log("foo");
|
||||
else
|
||||
o.q = console.log("bar");
|
||||
o.r = console.log("baz");
|
||||
}
|
||||
f(42);
|
||||
f(null);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
if (a)
|
||||
console.log("foo");
|
||||
else
|
||||
console.log("bar");
|
||||
console.log("baz");
|
||||
}
|
||||
f(42);
|
||||
f(null);
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"baz",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
}
|
||||
|
||||
reassign_1: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS", b = "FAIL";
|
||||
(b = a).toString();
|
||||
console.log(b);
|
||||
}
|
||||
expect: {
|
||||
var b = "FAIL";
|
||||
(b = "PASS").toString();
|
||||
console.log(b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
reassign_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
if (false) {
|
||||
a = null + 0;
|
||||
a();
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
if (false) {
|
||||
a = 0;
|
||||
a();
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
reassign_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = 0;
|
||||
(a = a || "PASS").toString();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = 0;
|
||||
(a = (0, "PASS")).toString();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
retain_instance_write: {
|
||||
options = {
|
||||
pure_getters: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
return a;
|
||||
}
|
||||
function g() {
|
||||
var o = {};
|
||||
var b = new f(o);
|
||||
if (console)
|
||||
b.p = "PASS";
|
||||
return o;
|
||||
}
|
||||
console.log(g().p);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
return a;
|
||||
}
|
||||
function g() {
|
||||
var o = {};
|
||||
var b = new f(o);
|
||||
if (console)
|
||||
b.p = "PASS";
|
||||
return o;
|
||||
}
|
||||
console.log(g().p);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
@@ -68,6 +68,7 @@ drop_console_2: {
|
||||
}
|
||||
|
||||
drop_value: {
|
||||
expression = true
|
||||
options = {
|
||||
expression: true,
|
||||
side_effects: true,
|
||||
@@ -106,6 +107,7 @@ wrongly_optimized: {
|
||||
}
|
||||
|
||||
negate_iife_1: {
|
||||
expression = true
|
||||
options = {
|
||||
expression: true,
|
||||
negate_iife: true,
|
||||
@@ -119,6 +121,7 @@ negate_iife_1: {
|
||||
}
|
||||
|
||||
negate_iife_3: {
|
||||
expression = true
|
||||
options = {
|
||||
conditionals: true,
|
||||
expression: true,
|
||||
@@ -133,6 +136,7 @@ negate_iife_3: {
|
||||
}
|
||||
|
||||
negate_iife_3_off: {
|
||||
expression = true
|
||||
options = {
|
||||
conditionals: true,
|
||||
expression: true,
|
||||
@@ -215,6 +219,7 @@ negate_iife_5_off: {
|
||||
}
|
||||
|
||||
issue_1254_negate_iife_true: {
|
||||
expression = true
|
||||
options = {
|
||||
expression: true,
|
||||
negate_iife: true,
|
||||
@@ -226,11 +231,12 @@ issue_1254_negate_iife_true: {
|
||||
};
|
||||
})()();
|
||||
}
|
||||
expect_exact: '(function(){return function(){console.log("test")}})()();'
|
||||
expect_exact: 'function(){return function(){console.log("test")}}()()'
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1254_negate_iife_nested: {
|
||||
expression = true
|
||||
options = {
|
||||
expression: true,
|
||||
negate_iife: true,
|
||||
@@ -242,7 +248,7 @@ issue_1254_negate_iife_nested: {
|
||||
};
|
||||
})()()()()();
|
||||
}
|
||||
expect_exact: '(function(){return function(){console.log("test")}})()()()()();'
|
||||
expect_exact: 'function(){return function(){console.log("test")}}()()()()()'
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
dont_reuse_prop: {
|
||||
mangle = {
|
||||
properties: {
|
||||
domprops: true,
|
||||
regex: /asd/,
|
||||
},
|
||||
}
|
||||
@@ -19,11 +20,17 @@ dont_reuse_prop: {
|
||||
console.log(obj.a);
|
||||
}
|
||||
expect_stdout: "123"
|
||||
expect_warnings: [
|
||||
"INFO: Preserving excluded property a",
|
||||
"INFO: Mapping property asd to b",
|
||||
"INFO: Preserving reserved property log",
|
||||
]
|
||||
}
|
||||
|
||||
unmangleable_props_should_always_be_reserved: {
|
||||
mangle = {
|
||||
properties: {
|
||||
domprops: true,
|
||||
regex: /asd/,
|
||||
},
|
||||
}
|
||||
@@ -42,4 +49,9 @@ unmangleable_props_should_always_be_reserved: {
|
||||
console.log(obj.a);
|
||||
}
|
||||
expect_stdout: "123"
|
||||
expect_warnings: [
|
||||
"INFO: Preserving excluded property a",
|
||||
"INFO: Mapping property asd to b",
|
||||
"INFO: Preserving reserved property log",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
keep_var_for_in: {
|
||||
options = {
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(obj){
|
||||
(function(obj) {
|
||||
var foo = 5;
|
||||
for (var i in obj)
|
||||
return foo;
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function(obj){
|
||||
(function(obj) {
|
||||
var i, foo = 5;
|
||||
for (i in obj)
|
||||
return foo;
|
||||
|
||||
@@ -16,6 +16,105 @@ join_vars_assign: {
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
join_array_assignments_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function () {
|
||||
var a = [ "foo", , "bar" ];
|
||||
a[1] = "baz";
|
||||
a[7] = "moo";
|
||||
a[0] = "moz";
|
||||
return a;
|
||||
}().join());
|
||||
}
|
||||
expect: {
|
||||
console.log(function () {
|
||||
var a = [ "moz", "baz", "bar", , , , , "moo" ];
|
||||
return a;
|
||||
}().join());
|
||||
}
|
||||
expect_stdout: "moz,baz,bar,,,,,moo"
|
||||
}
|
||||
|
||||
join_array_assignments_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function () {
|
||||
var a = [ "foo" ];
|
||||
a[1] = "bar";
|
||||
a[7] = "baz";
|
||||
a[2] = "moo";
|
||||
return a;
|
||||
}().join());
|
||||
}
|
||||
expect: {
|
||||
console.log(function () {
|
||||
var a = [ "foo", "bar" ];
|
||||
a[7] = "baz";
|
||||
a[2] = "moo";
|
||||
return a;
|
||||
}().join());
|
||||
}
|
||||
expect_stdout: "foo,bar,moo,,,,,baz"
|
||||
}
|
||||
|
||||
join_array_assignments_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function () {
|
||||
var a = [ "foo" ];
|
||||
a[1] = "bar";
|
||||
a.b = "baz";
|
||||
a[2] = "moo";
|
||||
return a;
|
||||
}().join());
|
||||
}
|
||||
expect: {
|
||||
console.log(function () {
|
||||
var a = [ "foo", "bar" ];
|
||||
a.b = "baz";
|
||||
a[2] = "moo";
|
||||
return a;
|
||||
}().join());
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
join_array_assignments_4: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function () {
|
||||
var a = [ "foo" ];
|
||||
a[0] = "bar";
|
||||
a[1] = a;
|
||||
a[2] = "baz";
|
||||
return a;
|
||||
}().join());
|
||||
}
|
||||
expect: {
|
||||
console.log(function () {
|
||||
var a = [ "bar" ];
|
||||
a[1] = a;
|
||||
a[2] = "baz";
|
||||
return a;
|
||||
}().join());
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
join_object_assignments_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
@@ -570,7 +669,7 @@ inlined_assignments: {
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
inilne_for: {
|
||||
inline_for: {
|
||||
options = {
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
@@ -590,7 +689,7 @@ inilne_for: {
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
inilne_var: {
|
||||
inline_var: {
|
||||
options = {
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
@@ -1394,3 +1493,37 @@ issue_5175: {
|
||||
}
|
||||
expect_stdout: "PASS PASS"
|
||||
}
|
||||
|
||||
issue_5831: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
var a = [ console.log("PASS") ];
|
||||
a[0] = 42;
|
||||
}
|
||||
expect: {
|
||||
var a = [ (console.log("PASS"), 42) ];
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5849: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
a = [ 42 ];
|
||||
a[0] = "PASS";
|
||||
console.log(a.join(""));
|
||||
}
|
||||
expect: {
|
||||
var a, a = [ "PASS" ];
|
||||
console.log(a.join(""));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -111,6 +111,7 @@ labels_5: {
|
||||
labels_6: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
out: break out;
|
||||
@@ -208,6 +209,59 @@ labels_10: {
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
labels_11: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
L: if (console.log("PASS"))
|
||||
break L;
|
||||
}
|
||||
expect: {
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
labels_12: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
L: try {
|
||||
if (console.log("foo"))
|
||||
break L;
|
||||
throw "bar";
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
break L;
|
||||
} finally {
|
||||
if (console.log("baz"))
|
||||
break L;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
L: try {
|
||||
if (!console.log("foo"))
|
||||
throw "bar";
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
} finally {
|
||||
if (console.log("baz"))
|
||||
break L;
|
||||
}
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
}
|
||||
|
||||
issue_4466_1: {
|
||||
mangle = {
|
||||
v8: false,
|
||||
@@ -327,3 +381,53 @@ issue_4466_2_toplevel_v8: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5522: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
L: try {
|
||||
return "FAIL";
|
||||
} finally {
|
||||
break L;
|
||||
}
|
||||
return "PASS";
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
L: try {
|
||||
return "FAIL";
|
||||
} finally {
|
||||
break L;
|
||||
}
|
||||
return "PASS";
|
||||
}());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5524: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
L: try {
|
||||
FAIL;
|
||||
} finally {
|
||||
break L;
|
||||
}
|
||||
console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
L: try {
|
||||
FAIL;
|
||||
} finally {
|
||||
break L;
|
||||
}
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -190,6 +190,96 @@ if_dead_branch: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
retain_tail_1: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
var b = "foo";
|
||||
if (a) {
|
||||
let b = "bar";
|
||||
while (console.log("baz"));
|
||||
console.log(b);
|
||||
} else {
|
||||
while (console.log("moo"));
|
||||
console.log(b);
|
||||
}
|
||||
}
|
||||
f();
|
||||
f(42);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
var b = "foo";
|
||||
if (a) {
|
||||
let b = "bar";
|
||||
while (console.log("baz"));
|
||||
console.log(b);
|
||||
} else {
|
||||
while (console.log("moo"));
|
||||
console.log(b);
|
||||
}
|
||||
}
|
||||
f();
|
||||
f(42);
|
||||
}
|
||||
expect_stdout: [
|
||||
"moo",
|
||||
"foo",
|
||||
"baz",
|
||||
"bar",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
retain_tail_2: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
var b = "foo";
|
||||
if (a) {
|
||||
while (console.log("bar"));
|
||||
console.log(b);
|
||||
} else {
|
||||
let b = "baz";
|
||||
while (console.log("moo"));
|
||||
console.log(b);
|
||||
}
|
||||
}
|
||||
f();
|
||||
f(42);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
var b = "foo";
|
||||
if (a) {
|
||||
while (console.log("bar"));
|
||||
console.log(b);
|
||||
} else {
|
||||
let b = "baz";
|
||||
while (console.log("moo"));
|
||||
console.log(b);
|
||||
}
|
||||
}
|
||||
f();
|
||||
f(42);
|
||||
}
|
||||
expect_stdout: [
|
||||
"moo",
|
||||
"baz",
|
||||
"bar",
|
||||
"foo",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
merge_vars_1: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
@@ -892,6 +982,40 @@ if_return_2: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
if_return_3: {
|
||||
options = {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var a = "PASS";
|
||||
function f(b) {
|
||||
if (console) {
|
||||
let b = a;
|
||||
return b;
|
||||
} else
|
||||
while (console.log("FAIL 1"));
|
||||
return b;
|
||||
}
|
||||
console.log(f("FAIL 2"));
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var a = "PASS";
|
||||
function f(b) {
|
||||
if (console) {
|
||||
let b = a;
|
||||
return b;
|
||||
} else
|
||||
while (console.log("FAIL 1"));
|
||||
return b;
|
||||
}
|
||||
console.log(f("FAIL 2"));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
do_if_continue_1: {
|
||||
options = {
|
||||
if_return: true,
|
||||
@@ -1006,6 +1130,130 @@ default_init: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
join_let_var_1: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var a = "foo";
|
||||
let b = "bar";
|
||||
for (var c of [ a, b ])
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
let a = "foo", b = "bar";
|
||||
for (var c of [ a, b ])
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
join_let_var_2: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
let a = "foo";
|
||||
var b = "bar";
|
||||
for (let c of [ a, b ])
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
let a = "foo", b = "bar";
|
||||
for (let c of [ a, b ])
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
keep_let_var_1: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var a = "foo";
|
||||
let b = "bar";
|
||||
for (var c of [ a, b ])
|
||||
console.log(c);
|
||||
function f() {
|
||||
return a;
|
||||
}
|
||||
console.log(f(f));
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var a = "foo", c;
|
||||
let b = "bar";
|
||||
for (c of [ a, b ])
|
||||
console.log(c);
|
||||
function f() {
|
||||
return a;
|
||||
}
|
||||
console.log(f(f));
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"foo",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
keep_let_var_2: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
let a = "foo";
|
||||
var b = "bar";
|
||||
for (let c of [ a, b ])
|
||||
console.log(c);
|
||||
function f() {
|
||||
return b;
|
||||
}
|
||||
console.log(f(f));
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
let a = "foo";
|
||||
var b = "bar";
|
||||
for (let c of [ a, b ])
|
||||
console.log(c);
|
||||
function f() {
|
||||
return b;
|
||||
}
|
||||
console.log(f(f));
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"bar",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_4191: {
|
||||
options = {
|
||||
functions: true,
|
||||
@@ -1625,7 +1873,7 @@ issue_4438: {
|
||||
function f() {
|
||||
if (console) {
|
||||
let a = console.log;
|
||||
void a("PASS");
|
||||
a("PASS");
|
||||
}
|
||||
}
|
||||
f();
|
||||
@@ -1998,3 +2246,323 @@ issue_5476: {
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5591: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
switch (console.log("foo")) {
|
||||
case console.log("bar"):
|
||||
if (console.log("baz"))
|
||||
return;
|
||||
else {
|
||||
let a;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case null:
|
||||
FAIL;
|
||||
}
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
switch (console.log("foo")) {
|
||||
case console.log("bar"):
|
||||
if (console.log("baz"))
|
||||
return;
|
||||
else {
|
||||
let a;
|
||||
return;
|
||||
}
|
||||
case null:
|
||||
FAIL;
|
||||
}
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5741: {
|
||||
options = {
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
(function(a) {
|
||||
let b = function() {
|
||||
var c = a;
|
||||
console.log(c);
|
||||
}();
|
||||
function g() {
|
||||
a++;
|
||||
b;
|
||||
}
|
||||
})("PASS");
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
(function(a) {
|
||||
let b = (c = a, void console.log(c));
|
||||
var c;
|
||||
function g() {
|
||||
a++;
|
||||
b;
|
||||
}
|
||||
})("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5745_1: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
{
|
||||
let f = function() {
|
||||
return f && "PASS";
|
||||
};
|
||||
var a = f();
|
||||
}
|
||||
a;
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
{
|
||||
let f = function() {
|
||||
return f && "PASS";
|
||||
};
|
||||
var a = f();
|
||||
}
|
||||
a;
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5745_2: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
{
|
||||
let f = function() {
|
||||
return f && "PASS";
|
||||
};
|
||||
var a = f();
|
||||
a;
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
{
|
||||
let f = function() {
|
||||
return f && "PASS";
|
||||
}, a = f();
|
||||
a;
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5756_1: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
loops: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
do {
|
||||
function f() {
|
||||
return b;
|
||||
}
|
||||
var a = "PASS".toString();
|
||||
let b;
|
||||
console.log(a);
|
||||
} while (!console);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
do {
|
||||
function f() {
|
||||
return b;
|
||||
}
|
||||
let a = "PASS".toString(), b;
|
||||
console.log(a);
|
||||
} while (!console);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5756_2: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function f() {
|
||||
let a = console.log("PASS");
|
||||
{
|
||||
var b;
|
||||
for (var c in b) {
|
||||
b;
|
||||
var c = function() {
|
||||
a;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
(function() {
|
||||
let a = console.log("PASS"), b;
|
||||
for (c in b) {
|
||||
b;
|
||||
var c = function() {
|
||||
a;
|
||||
};
|
||||
}
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5756_3: {
|
||||
options = {
|
||||
module: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
varify: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
console.log(f()());
|
||||
function f() {
|
||||
const a = "PASS";
|
||||
return function() {
|
||||
return a;
|
||||
};
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log(function() {
|
||||
let a = "PASS";
|
||||
return function() {
|
||||
return a;
|
||||
};
|
||||
}()());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5759: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function f() {
|
||||
for (var a in [ true ]) {
|
||||
let b;
|
||||
(function() {
|
||||
var c = void 0;
|
||||
b;
|
||||
console.log(c);
|
||||
var d = null;
|
||||
console.log(c);
|
||||
})();
|
||||
}
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function f() {
|
||||
for (var a in [ true ]) {
|
||||
let b;
|
||||
var c = c = void 0;
|
||||
b;
|
||||
console.log(c);
|
||||
console.log(c);
|
||||
}
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect_stdout: [
|
||||
"undefined",
|
||||
"undefined",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5787: {
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
let a = 42;
|
||||
switch (a) {
|
||||
case 42:
|
||||
// Node.js v4 (vm): SyntaxError: Identifier 'a' has already been declared
|
||||
let a = "PASS";
|
||||
return a;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
let a = 42;
|
||||
switch (a) {
|
||||
case 42:
|
||||
let a = "PASS";
|
||||
return a;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
@@ -3845,3 +3845,158 @@ issue_5471_2: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5714: {
|
||||
options = {
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
loops: true,
|
||||
merge_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
console.log(function() {
|
||||
var i = 1;
|
||||
while (i--) {
|
||||
var a = function f(b) {
|
||||
console.log(b);
|
||||
var c = function(d) {
|
||||
console.log(typeof d);
|
||||
}(console);
|
||||
}();
|
||||
var e = 42;
|
||||
}
|
||||
return e;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log(function() {
|
||||
for (var i = 1; i--;) {
|
||||
var b = void 0;
|
||||
console.log(b);
|
||||
b = console,
|
||||
console.log(typeof b);
|
||||
var e = 42;
|
||||
}
|
||||
return e;
|
||||
}());
|
||||
}
|
||||
expect_stdout: [
|
||||
"undefined",
|
||||
"object",
|
||||
"42",
|
||||
]
|
||||
}
|
||||
|
||||
issue_5770_1: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
loops: true,
|
||||
merge_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
L: do {
|
||||
if (console)
|
||||
for (var a = "FAIL 1"; a; a--)
|
||||
continue L;
|
||||
var b = "FAIL 2";
|
||||
} while (console.log(b || "PASS"));
|
||||
}
|
||||
expect: {
|
||||
L: do {
|
||||
if (console) {
|
||||
var a = "FAIL 1";
|
||||
if (a)
|
||||
continue L;
|
||||
}
|
||||
var b = "FAIL 2";
|
||||
} while (console.log(b || "PASS"));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5770_2: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
if_return: true,
|
||||
loops: true,
|
||||
merge_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
L: do {
|
||||
for (var a = "FAIL 1"; a; a--)
|
||||
continue L;
|
||||
var b = "FAIL 2";
|
||||
} while (console.log(b || "PASS"));
|
||||
}
|
||||
expect: {
|
||||
L: do {
|
||||
var a = "FAIL 1";
|
||||
var b;
|
||||
} while (a || (b = "FAIL 2"), console.log(b || "PASS"));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5772_1: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
merge_vars: true,
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
(function(a) {
|
||||
while (--a)
|
||||
return;
|
||||
var b = console.log("foo") && (c = 42) ? 0 : console.log(c);
|
||||
var c = b;
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function(a) {
|
||||
if (--a)
|
||||
return;
|
||||
var a = console.log("foo") && (c = 42) ? 0 : console.log(c);
|
||||
var c = a;
|
||||
})();
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"undefined",
|
||||
]
|
||||
}
|
||||
|
||||
issue_5772_2: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
merge_vars: true,
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
(function(a) {
|
||||
while (--a)
|
||||
return;
|
||||
var b;
|
||||
var c = console.log("foo") && (b = 1) ? 2 : 3;
|
||||
console.log(b, c);
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function(a) {
|
||||
if (--a)
|
||||
return;
|
||||
var b;
|
||||
var a = console.log("foo") && (b = 1) ? 2 : 3;
|
||||
console.log(b, a);
|
||||
})();
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"undefined 3",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -308,6 +308,7 @@ issue_4679: {
|
||||
issue_5266: {
|
||||
options = {
|
||||
inline: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
[
|
||||
@@ -343,3 +344,43 @@ issue_5266: {
|
||||
]
|
||||
node_version: ">=14"
|
||||
}
|
||||
|
||||
issue_5829_1: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
}
|
||||
input: {
|
||||
(function f(a) {
|
||||
var b;
|
||||
(!a ?? (b = 0)) || console.log(b || "PASS");
|
||||
})("FAIL");
|
||||
}
|
||||
expect: {
|
||||
(function f(a) {
|
||||
var b;
|
||||
(!a ?? (b = 0)) || console.log(b || "PASS");
|
||||
})("FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=14"
|
||||
}
|
||||
|
||||
issue_5829_2: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
}
|
||||
input: {
|
||||
(function f(a) {
|
||||
var b;
|
||||
(a ?? (b = 0)) && console.log(b || "PASS");
|
||||
})("FAIL");
|
||||
}
|
||||
expect: {
|
||||
(function f(a) {
|
||||
var b;
|
||||
(a ?? (b = 0)) && console.log(b || "PASS");
|
||||
})("FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=14"
|
||||
}
|
||||
|
||||
@@ -173,7 +173,9 @@ numeric_literal: {
|
||||
side_effects: true,
|
||||
}
|
||||
mangle = {
|
||||
properties: true,
|
||||
properties: {
|
||||
domprops: true,
|
||||
},
|
||||
}
|
||||
beautify = {
|
||||
beautify: true,
|
||||
|
||||
@@ -617,3 +617,33 @@ issue_5292_sub_pure_getters_strict: {
|
||||
]
|
||||
node_version: ">=14"
|
||||
}
|
||||
|
||||
issue_5856: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
var a;
|
||||
a?.p;
|
||||
a.q;
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
try {
|
||||
var a;
|
||||
a?.p;
|
||||
a.q;
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=14"
|
||||
}
|
||||
|
||||
@@ -133,6 +133,7 @@ evaluate_string_length: {
|
||||
mangle_properties_1: {
|
||||
mangle = {
|
||||
properties: {
|
||||
domprops: true,
|
||||
keep_quoted: false,
|
||||
},
|
||||
}
|
||||
@@ -147,17 +148,18 @@ mangle_properties_1: {
|
||||
a["a"] = "bar";
|
||||
a.b = "red";
|
||||
x = {o: 10};
|
||||
a.r(x.o, a.a);
|
||||
a['r']({b: "blue", a: "baz"});
|
||||
a.run(x.o, a.a);
|
||||
a['run']({b: "blue", a: "baz"});
|
||||
}
|
||||
}
|
||||
|
||||
mangle_properties_2: {
|
||||
mangle = {
|
||||
properties: {
|
||||
domprops: true,
|
||||
reserved: [
|
||||
"value",
|
||||
]
|
||||
],
|
||||
},
|
||||
}
|
||||
input: {
|
||||
@@ -199,6 +201,24 @@ mangle_properties_2: {
|
||||
]
|
||||
}
|
||||
|
||||
mangle_properties_3: {
|
||||
mangle = {
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
console.log({
|
||||
[(console, "foo")]: "PASS",
|
||||
}.foo);
|
||||
}
|
||||
expect: {
|
||||
console.log({
|
||||
[(console, "o")]: "PASS",
|
||||
}.o);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
mangle_unquoted_properties: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
@@ -206,6 +226,8 @@ mangle_unquoted_properties: {
|
||||
}
|
||||
mangle = {
|
||||
properties: {
|
||||
builtins: true,
|
||||
domprops: true,
|
||||
keep_quoted: true,
|
||||
},
|
||||
}
|
||||
@@ -305,7 +327,9 @@ mangle_debug_suffix_keep_quoted: {
|
||||
}
|
||||
mangle = {
|
||||
properties: {
|
||||
builtins: true,
|
||||
debug: "XYZ",
|
||||
domprops: true,
|
||||
keep_quoted: true,
|
||||
reserved: [],
|
||||
},
|
||||
@@ -351,6 +375,68 @@ mangle_debug_suffix_keep_quoted: {
|
||||
}
|
||||
}
|
||||
|
||||
keep_substituted_property: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
properties: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
mangle = {
|
||||
properties: {
|
||||
keep_quoted: true,
|
||||
},
|
||||
}
|
||||
input: {
|
||||
var o = { p: [] };
|
||||
function f(b) {
|
||||
return o[b];
|
||||
}
|
||||
function g() {
|
||||
var a = "p";
|
||||
return o[a] === f(a);
|
||||
}
|
||||
console.log(g() ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
var o = { p: [] };
|
||||
function f(n) {
|
||||
return o[n];
|
||||
}
|
||||
function g() {
|
||||
var n = "p";
|
||||
return o.p === f(n);
|
||||
}
|
||||
console.log(g() ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
keep_substituted_property_quotes: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
properties: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
beautify = {
|
||||
keep_quoted_props: true,
|
||||
}
|
||||
input: {
|
||||
function f(o) {
|
||||
var a = "p";
|
||||
return o[a];
|
||||
}
|
||||
console.log(f({ p: "PASS" }));
|
||||
}
|
||||
expect: {
|
||||
function f(o) {
|
||||
var a = "p";
|
||||
return o["p"];
|
||||
}
|
||||
console.log(f({ p: "PASS" }));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
first_256_chars_as_properties: {
|
||||
beautify = {
|
||||
ascii_only: true,
|
||||
@@ -897,12 +983,15 @@ issue_2256: {
|
||||
},
|
||||
}
|
||||
input: {
|
||||
({ "keep": 1 });
|
||||
g.keep = g.change;
|
||||
({ "keep": 42 });
|
||||
global.keep = global.change = "PASS";
|
||||
console.log(keep);
|
||||
}
|
||||
expect: {
|
||||
g.keep = g.g;
|
||||
global.keep = global.l = "PASS";
|
||||
console.log(keep);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
lhs_prop_1: {
|
||||
@@ -1578,3 +1667,163 @@ issue_5177: {
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5682_in_1: {
|
||||
mangle = {
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
return "foo" in a;
|
||||
}
|
||||
var o = {};
|
||||
var p = "foo";
|
||||
o[p] = 42;
|
||||
console.log(f(o) ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
function f(o) {
|
||||
return "foo" in o;
|
||||
}
|
||||
var o = {};
|
||||
var p = "foo";
|
||||
o[p] = 42;
|
||||
console.log(f(o) ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5682_in_2: {
|
||||
mangle = {
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
return "foo" in a;
|
||||
}
|
||||
var o = { foo: 42 };
|
||||
console.log(f(o) ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
function f(o) {
|
||||
return "o" in o;
|
||||
}
|
||||
var o = { o: 42 };
|
||||
console.log(f(o) ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5682_dot_1: {
|
||||
mangle = {
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
return a.foo;
|
||||
}
|
||||
var o = {};
|
||||
var p = "foo";
|
||||
o[p] = "PASS";
|
||||
console.log(f(o));
|
||||
}
|
||||
expect: {
|
||||
function f(o) {
|
||||
return o.foo;
|
||||
}
|
||||
var o = {};
|
||||
var p = "foo";
|
||||
o[p] = "PASS";
|
||||
console.log(f(o));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5682_dot_2: {
|
||||
mangle = {
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
return a.foo;
|
||||
}
|
||||
var o = { foo: "PASS" };
|
||||
console.log(f(o));
|
||||
}
|
||||
expect: {
|
||||
function f(o) {
|
||||
return o.o;
|
||||
}
|
||||
var o = { o: "PASS" };
|
||||
console.log(f(o));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5682_dot_2_computed: {
|
||||
mangle = {
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
return a.foo;
|
||||
}
|
||||
var o = { ["foo"]: "PASS" };
|
||||
console.log(f(o));
|
||||
}
|
||||
expect: {
|
||||
function f(o) {
|
||||
return o.o;
|
||||
}
|
||||
var o = { ["o"]: "PASS" };
|
||||
console.log(f(o));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5682_sub_1: {
|
||||
mangle = {
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
return a["foo"];
|
||||
}
|
||||
var o = {};
|
||||
var p = "foo";
|
||||
o[p] = "PASS";
|
||||
console.log(f(o));
|
||||
}
|
||||
expect: {
|
||||
function f(o) {
|
||||
return o["foo"];
|
||||
}
|
||||
var o = {};
|
||||
var p = "foo";
|
||||
o[p] = "PASS";
|
||||
console.log(f(o));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5682_sub_2: {
|
||||
mangle = {
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
return a["foo"];
|
||||
}
|
||||
var o = { foo: "PASS" };
|
||||
console.log(f(o));
|
||||
}
|
||||
expect: {
|
||||
function f(o) {
|
||||
return o["o"];
|
||||
}
|
||||
var o = { o: "PASS" };
|
||||
console.log(f(o));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ relational: {
|
||||
"bar" >= "bar";
|
||||
}
|
||||
expect: {
|
||||
0 instanceof bar();
|
||||
[] instanceof bar();
|
||||
bar();
|
||||
bar(), bar();
|
||||
bar();
|
||||
|
||||
@@ -1540,10 +1540,12 @@ this_toString: {
|
||||
issue_4803: {
|
||||
options = {
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
@@ -1685,3 +1687,31 @@ issue_4939: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5856: {
|
||||
options = {
|
||||
pure_getters: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = [ "FAIL", "PASS" ];
|
||||
(function(b) {
|
||||
var c = b[0];
|
||||
b[0] = b[1];
|
||||
b[1] = c;
|
||||
})(a);
|
||||
console.log(a[0]);
|
||||
}
|
||||
expect: {
|
||||
var a = [ "FAIL", "PASS" ];
|
||||
(function(b) {
|
||||
var c = b[0];
|
||||
b[0] = b[1];
|
||||
b[1] = c;
|
||||
})(a);
|
||||
console.log(a[0]);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -2488,7 +2488,7 @@ side_effects_assign: {
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = typeof void (a && a.in);
|
||||
var a = "undefined";
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
@@ -2530,7 +2530,8 @@ pure_getters_2: {
|
||||
var a = a && a.b;
|
||||
}
|
||||
expect: {
|
||||
var a = a && a.b;
|
||||
var a;
|
||||
a && a.b;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5424,7 +5425,7 @@ issue_2774: {
|
||||
get a() {
|
||||
var b;
|
||||
(b = true) && b.c;
|
||||
b = void 0;
|
||||
void 0;
|
||||
}
|
||||
}.a);
|
||||
}
|
||||
@@ -7896,3 +7897,452 @@ issue_5434: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5623: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = 0;
|
||||
function f() {
|
||||
var b = a;
|
||||
a = b;
|
||||
}
|
||||
f && f((a++ && a).toString());
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = 0;
|
||||
function f() {
|
||||
var b;
|
||||
a = a;
|
||||
}
|
||||
f((a++ && a).toString());
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_5716_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
inline: true,
|
||||
merge_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
function f() {
|
||||
var b = [ c, c ], c = function() {
|
||||
return b++ + (a = b);
|
||||
}();
|
||||
}
|
||||
f();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
c = [ c, c ],
|
||||
void (c = ++c);
|
||||
var c;
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: "NaN"
|
||||
}
|
||||
|
||||
issue_5716_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
inline: true,
|
||||
merge_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
function f() {
|
||||
var b = [ c, c ], c = function() {
|
||||
return (b += 4) + (a = b += 2);
|
||||
}();
|
||||
}
|
||||
f();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
void (c = c = (c = [ c, c ]) + 4 + 2);
|
||||
var c;
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: ",42"
|
||||
}
|
||||
|
||||
issue_5716_3: {
|
||||
options = {
|
||||
assignments: true,
|
||||
collapse_vars: true,
|
||||
inline: true,
|
||||
merge_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
function f() {
|
||||
var b = [ c, c ], c = function() {
|
||||
return (b = b + 4) + (a = b += 2);
|
||||
}();
|
||||
}
|
||||
f();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
void (c = c = (c = [ c, c ]) + 4 + 2);
|
||||
var c;
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: ",42"
|
||||
}
|
||||
|
||||
issue_5716_4: {
|
||||
options = {
|
||||
assignments: true,
|
||||
collapse_vars: true,
|
||||
inline: true,
|
||||
merge_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
function f() {
|
||||
var b = [ c, c ], c = function() {
|
||||
return (b = true | b) + (a = b *= 42);
|
||||
}();
|
||||
}
|
||||
f();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
void (c = c = ((c = [ c, c ]) | true) * 42);
|
||||
var c;
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
issue_5716_5: {
|
||||
options = {
|
||||
assignments: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
return 0 || (a = 42 | a);
|
||||
var a = function() {
|
||||
return a;
|
||||
};
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
return 0 || (a |= 42);
|
||||
var a = function() {
|
||||
return a;
|
||||
};
|
||||
}());
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
issue_5730_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
L: {
|
||||
var f = function() {
|
||||
console.log(a);
|
||||
};
|
||||
}
|
||||
f();
|
||||
a++;
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
var f = function() {
|
||||
console.log(a);
|
||||
};
|
||||
f();
|
||||
a++;
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5730_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
try {
|
||||
var f = function() {
|
||||
console.log(a);
|
||||
};
|
||||
} finally {}
|
||||
f();
|
||||
a++;
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
try {
|
||||
var f = function() {
|
||||
console.log(a);
|
||||
};
|
||||
} finally {}
|
||||
f();
|
||||
a++;
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5730_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var f, a = "PASS";
|
||||
L: {
|
||||
f = function() {
|
||||
console.log(a);
|
||||
};
|
||||
}
|
||||
f();
|
||||
a++;
|
||||
}
|
||||
expect: {
|
||||
var f, a = "PASS";
|
||||
f = function() {
|
||||
console.log(a);
|
||||
};
|
||||
f();
|
||||
a++;
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5777_1: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
(function(a) {
|
||||
function g() {
|
||||
h();
|
||||
}
|
||||
g();
|
||||
a = function() {};
|
||||
function h() {
|
||||
console.log(a);
|
||||
}
|
||||
})("PASS");
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
(function(a) {
|
||||
(function() {
|
||||
h();
|
||||
})();
|
||||
a = function() {};
|
||||
function h() {
|
||||
console.log(a);
|
||||
}
|
||||
})("PASS");
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5777_2: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
(function() {
|
||||
function g() {
|
||||
h();
|
||||
}
|
||||
g();
|
||||
a = function() {};
|
||||
function h() {
|
||||
console.log(a);
|
||||
}
|
||||
})();
|
||||
}
|
||||
f("PASS");
|
||||
}
|
||||
expect: {
|
||||
(function(a) {
|
||||
(function() {
|
||||
(function() {
|
||||
h();
|
||||
})();
|
||||
a = function() {};
|
||||
function h() {
|
||||
console.log(a);
|
||||
}
|
||||
})();
|
||||
})("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_1666: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var x = 42;
|
||||
{
|
||||
x();
|
||||
function x() {
|
||||
console.log("foo");
|
||||
}
|
||||
}
|
||||
console.log(typeof x);
|
||||
}
|
||||
expect: {
|
||||
var x = 42;
|
||||
{
|
||||
x();
|
||||
function x() {
|
||||
console.log("foo");
|
||||
}
|
||||
}
|
||||
console.log(typeof x);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1666_strict: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var x = 42;
|
||||
{
|
||||
x();
|
||||
function x() {
|
||||
console.log("foo");
|
||||
}
|
||||
}
|
||||
console.log(typeof x);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var x = 42;
|
||||
{
|
||||
x();
|
||||
function x() {
|
||||
console.log("foo");
|
||||
}
|
||||
}
|
||||
console.log(typeof x);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1666_undefined: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var undefined = 42;
|
||||
{
|
||||
undefined();
|
||||
function undefined() {
|
||||
console.log("foo");
|
||||
}
|
||||
}
|
||||
console.log(typeof undefined);
|
||||
}
|
||||
expect: {
|
||||
var undefined = 42;
|
||||
{
|
||||
undefined();
|
||||
function undefined() {
|
||||
console.log("foo");
|
||||
}
|
||||
}
|
||||
console.log(typeof undefined);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1666_undefined_strict: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var undefined = 42;
|
||||
{
|
||||
undefined();
|
||||
function undefined() {
|
||||
console.log("foo");
|
||||
}
|
||||
}
|
||||
console.log(typeof undefined);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var undefined = 42;
|
||||
{
|
||||
undefined();
|
||||
function undefined() {
|
||||
console.log("foo");
|
||||
}
|
||||
}
|
||||
console.log(typeof undefined);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
@@ -739,3 +739,55 @@ issue_3480_ie8_toplevel: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5787_1: {
|
||||
rename = true
|
||||
input: {
|
||||
console.log(function() {
|
||||
const a = 42;
|
||||
switch (a) {
|
||||
case 42:
|
||||
const a = "PASS";
|
||||
return a;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
const a = 42;
|
||||
switch (a) {
|
||||
case 42:
|
||||
const a = "PASS";
|
||||
return a;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_5787_2: {
|
||||
rename = true
|
||||
input: {
|
||||
console.log(function() {
|
||||
let a = 42;
|
||||
switch (a) {
|
||||
case 42:
|
||||
// Node.js v4 (vm): SyntaxError: Identifier 'a' has already been declared
|
||||
let a = "PASS";
|
||||
return a;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
let a = 42;
|
||||
switch (a) {
|
||||
case 42:
|
||||
let b = "PASS";
|
||||
return b;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
@@ -648,7 +648,7 @@ drop_new_function: {
|
||||
}
|
||||
expect: {
|
||||
void ([ ... {
|
||||
[console.log("PASS")]: [].e,
|
||||
[console.log("PASS")]: [][0],
|
||||
}] = []);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
@@ -1363,3 +1363,282 @@ issue_5391: {
|
||||
expect_stdout: "NaN"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
issue_5533_1_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(...b) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_1_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(...b) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_2_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(...[ b ]) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_2_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(...[ b ]) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5552_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var log = console.log;
|
||||
var a = f, b = log();
|
||||
function f(...[ c = a = "PASS" ]) {}
|
||||
f((a = "FAIL", b));
|
||||
log(a);
|
||||
}
|
||||
expect: {
|
||||
var log = console.log;
|
||||
var a = f, b = log();
|
||||
function f(...[ c = a = "PASS" ]) {}
|
||||
f((a = "FAIL", b));
|
||||
log(a);
|
||||
}
|
||||
expect_stdout: [
|
||||
"",
|
||||
"PASS",
|
||||
]
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5552_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var log = console.log;
|
||||
var a = f;
|
||||
function f(...{ [a = "PASS"]: b }) {}
|
||||
f((a = "FAIL", 42));
|
||||
log(a);
|
||||
}
|
||||
expect: {
|
||||
var log = console.log;
|
||||
var a = f;
|
||||
function f(...{ [a = "PASS"]: b }) {}
|
||||
f((a = "FAIL", 42));
|
||||
log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5552_3: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = [ "FAIL", "PASS" ];
|
||||
console.log(function(b, ...[ c = a.pop() ]) {
|
||||
return b;
|
||||
}(a.pop()));
|
||||
}
|
||||
expect: {
|
||||
var a = [ "FAIL", "PASS" ];
|
||||
console.log(function(b, ...[ c = a.pop() ]) {
|
||||
return b;
|
||||
}(a.pop()));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5552_4: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = [ "FAIL", "PASS" ];
|
||||
console.log(function(b, ...{ [a.pop()]: c }) {
|
||||
return b;
|
||||
}(a.pop()));
|
||||
}
|
||||
expect: {
|
||||
var a = [ "FAIL", "PASS" ];
|
||||
console.log(function(b, ...{ [a.pop()]: c }) {
|
||||
return b;
|
||||
}(a.pop()));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5705: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
rests: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(...a) {
|
||||
var b = { ...a };
|
||||
})(console.log("PASS"));
|
||||
}
|
||||
expect: {
|
||||
(function() {})(console.log("PASS"));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
@@ -125,6 +125,7 @@ log_nested: {
|
||||
|
||||
timers: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
@@ -132,26 +133,22 @@ timers: {
|
||||
input: {
|
||||
var count = 0, interval = 1000, duration = 3210;
|
||||
var timer = setInterval(function() {
|
||||
console.log(++count);
|
||||
if (!count++) setTimeout(function() {
|
||||
clearInterval(timer);
|
||||
console.log(count <= 4 ? "PASS" : "FAIL");
|
||||
}, duration);
|
||||
}, interval);
|
||||
setTimeout(function() {
|
||||
clearInterval(timer);
|
||||
}, duration);
|
||||
}
|
||||
expect: {
|
||||
var count = 0;
|
||||
var timer = setInterval(function() {
|
||||
console.log(++count);
|
||||
if (!count++) setTimeout(function() {
|
||||
clearInterval(timer);
|
||||
console.log(count <= 4 ? "PASS" : "FAIL");
|
||||
}, 3210);
|
||||
}, 1000);
|
||||
setTimeout(function() {
|
||||
clearInterval(timer);
|
||||
}, 3210);
|
||||
}
|
||||
expect_stdout: [
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
]
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=0.12"
|
||||
}
|
||||
|
||||
|
||||
@@ -318,6 +318,32 @@ unsafe_string_replace: {
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
unsafe_Object_call: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
f: function(a) {
|
||||
console.log(a ? this.p : "FAIL 1");
|
||||
},
|
||||
p: "FAIL 2",
|
||||
}, p = "PASS";
|
||||
Object(o.f)(42);
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
f: function(a) {
|
||||
console.log(a ? this.p : "FAIL 1");
|
||||
},
|
||||
p: "FAIL 2",
|
||||
}, p = "PASS";
|
||||
(0, o.f)(42);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
drop_value: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
@@ -698,3 +724,246 @@ retain_instanceof: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
drop_access: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var o = {};
|
||||
o.p;
|
||||
try {
|
||||
(function() {
|
||||
o.q;
|
||||
})();
|
||||
console.log("PASS");
|
||||
} catch (e) {
|
||||
console.log("FAIL");
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var o = {};
|
||||
o.p;
|
||||
try {
|
||||
console.log("PASS");
|
||||
} catch (e) {
|
||||
console.log("FAIL");
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
keep_access: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var o = {};
|
||||
o.p;
|
||||
o = null;
|
||||
try {
|
||||
(function() {
|
||||
o.q;
|
||||
})();
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var o = {};
|
||||
o.p;
|
||||
o = null;
|
||||
try {
|
||||
(function() {
|
||||
o.q;
|
||||
})();
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
keep_access_after_call: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var o = {};
|
||||
o.p;
|
||||
o.q;
|
||||
f();
|
||||
try {
|
||||
o.r;
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
function f() {
|
||||
o = null;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var o = {};
|
||||
o.p;
|
||||
f();
|
||||
try {
|
||||
o.r;
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
function f() {
|
||||
o = null;
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5860_drop_1: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var a = {};
|
||||
a.p;
|
||||
var a;
|
||||
a.q;
|
||||
console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
var a = {};
|
||||
a.p;
|
||||
var a;
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5860_drop_2: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
a = {};
|
||||
a.p;
|
||||
var a;
|
||||
a.q;
|
||||
console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
a = {};
|
||||
a.p;
|
||||
var a;
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5860_keep_1: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var a = {};
|
||||
a.p;
|
||||
a.q;
|
||||
var a = null;
|
||||
try {
|
||||
a.r;
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var a = {};
|
||||
a.p;
|
||||
var a = null;
|
||||
try {
|
||||
a.r;
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5860_keep_2: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
a = {};
|
||||
a.p;
|
||||
a.q;
|
||||
var a = null;
|
||||
try {
|
||||
a.r;
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
a = {};
|
||||
a.p;
|
||||
var a = null;
|
||||
try {
|
||||
a.r;
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5860_keep_3: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var a = {};
|
||||
a.p;
|
||||
a.q;
|
||||
a = null;
|
||||
try {
|
||||
a.r;
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var a = {};
|
||||
a.p;
|
||||
a = null;
|
||||
try {
|
||||
a.r;
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -1,15 +1,24 @@
|
||||
decimal: {
|
||||
input: {
|
||||
console.log({... 0.42});
|
||||
}
|
||||
expect_exact: "console.log({....42});"
|
||||
expect_stdout: "{}"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
collapse_vars_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
[ ...a = "PASS", "PASS"].slice();
|
||||
[ ...a = "PASS", "PASS" ].slice();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
[ ...a = "PASS", "PASS"].slice();
|
||||
[ ...a = "PASS", "PASS" ].slice();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
@@ -24,7 +33,7 @@ collapse_vars_2: {
|
||||
var a = "FAIL";
|
||||
try {
|
||||
a = "PASS";
|
||||
[ ...42, "PASS"].slice();
|
||||
[ ...42, "PASS" ].slice();
|
||||
} catch (e) {
|
||||
console.log(a);
|
||||
}
|
||||
@@ -33,7 +42,7 @@ collapse_vars_2: {
|
||||
var a = "FAIL";
|
||||
try {
|
||||
a = "PASS";
|
||||
[ ...42, "PASS"].slice();
|
||||
[ ...42, "PASS" ].slice();
|
||||
} catch (e) {
|
||||
console.log(a);
|
||||
}
|
||||
@@ -49,7 +58,7 @@ collapse_vars_3: {
|
||||
input: {
|
||||
var a = "FAIL";
|
||||
try {
|
||||
[ ...(a = "PASS", 42), "PASS"].slice();
|
||||
[ ...(a = "PASS", 42), "PASS" ].slice();
|
||||
} catch (e) {
|
||||
console.log(a);
|
||||
}
|
||||
@@ -57,7 +66,7 @@ collapse_vars_3: {
|
||||
expect: {
|
||||
var a = "FAIL";
|
||||
try {
|
||||
[ ...(a = "PASS", 42), "PASS"].slice();
|
||||
[ ...(a = "PASS", 42), "PASS" ].slice();
|
||||
} catch (e) {
|
||||
console.log(a);
|
||||
}
|
||||
@@ -1194,3 +1203,74 @@ issue_5382: {
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
issue_5602: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
if_return: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
sequences: true,
|
||||
spreads: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
try {
|
||||
var b = function(c) {
|
||||
if (c)
|
||||
return FAIL;
|
||||
var d = 42;
|
||||
}(...[ null, A = 0 ]);
|
||||
} catch (e) {
|
||||
b();
|
||||
}
|
||||
})();
|
||||
console.log(A);
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
try {
|
||||
var b = void (A = 0);
|
||||
} catch (e) {
|
||||
b();
|
||||
}
|
||||
})(),
|
||||
console.log(A);
|
||||
}
|
||||
expect_stdout: "0"
|
||||
expect_warnings: [
|
||||
"INFO: Dropping unused variable d [test/compress/spreads.js:6,24]",
|
||||
"INFO: Collapsing c [test/compress/spreads.js:4,24]",
|
||||
"INFO: Dropping unused variable c [test/compress/spreads.js:3,33]",
|
||||
"INFO: pass 0: last_count: Infinity, count: 27",
|
||||
"WARN: Condition always false [test/compress/spreads.js:4,20]",
|
||||
"INFO: Collapsing null [test/compress/spreads.js:7,23]",
|
||||
"INFO: Collapsing 0 [test/compress/spreads.js:3,24]",
|
||||
"INFO: pass 1: last_count: 27, count: 22",
|
||||
]
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5850: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = [ ..."FAIL" ];
|
||||
a[0] = "P";
|
||||
a[2] = a[3] = "S";
|
||||
console.log(a.join(""));
|
||||
}
|
||||
expect: {
|
||||
var a = [ ..."FAIL" ];
|
||||
a[0] = "P";
|
||||
a[2] = a[3] = "S";
|
||||
console.log(a.join(""));
|
||||
}
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
@@ -1608,3 +1608,83 @@ issue_5012: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5543_1: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
switch (a) {
|
||||
default:
|
||||
switch (42) {
|
||||
case a:
|
||||
case console.log("PASS"):
|
||||
}
|
||||
break;
|
||||
case null:
|
||||
switch (false) {
|
||||
case a:
|
||||
case console.log("FAIL"):
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
switch (a) {
|
||||
default:
|
||||
switch (42) {
|
||||
case a:
|
||||
case console.log("PASS"):
|
||||
}
|
||||
break;
|
||||
case null:
|
||||
switch (false) {
|
||||
case a:
|
||||
case console.log("FAIL"):
|
||||
}
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5543_2: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
switch (a) {
|
||||
default:
|
||||
switch (42) {
|
||||
case a:
|
||||
case console.log("PASS"):
|
||||
}
|
||||
break;
|
||||
case null:
|
||||
switch (42) {
|
||||
case a:
|
||||
case console.log("FAIL"):
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
switch (a) {
|
||||
default:
|
||||
switch (42) {
|
||||
case a:
|
||||
case console.log("PASS"):
|
||||
}
|
||||
break;
|
||||
case null:
|
||||
switch (42) {
|
||||
case a:
|
||||
case console.log("FAIL"):
|
||||
}
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ if_return: {
|
||||
if (w) {
|
||||
if (y) return;
|
||||
} else if (z) return;
|
||||
return x == y || (x && w(), y && z()), !0;
|
||||
return x != y && (x && w(), y) && z(), !0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,6 +194,43 @@ scope_adjustment_let: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
escaped_const: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
varify: true,
|
||||
}
|
||||
input: {
|
||||
const log = console.log;
|
||||
log("PASS");
|
||||
}
|
||||
expect: {
|
||||
var log = console.log;
|
||||
log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
escaped_let: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
varify: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
let log = console.log;
|
||||
log("PASS");
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var log = console.log;
|
||||
log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_4191_const: {
|
||||
options = {
|
||||
functions: true,
|
||||
@@ -292,6 +329,42 @@ forin_const_2: {
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
forin_const_3: {
|
||||
options = {
|
||||
module: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
varify: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
const o = {
|
||||
p: 42,
|
||||
q: "PASS",
|
||||
};
|
||||
for (const k in o)
|
||||
(function f() {
|
||||
console.log(k, o[k]);
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
let o = {
|
||||
p: 42,
|
||||
q: "PASS",
|
||||
};
|
||||
for (let k in o)
|
||||
(function f() {
|
||||
console.log(k, o[k]);
|
||||
})();
|
||||
}
|
||||
expect_stdout: [
|
||||
"p 42",
|
||||
"q PASS",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
forin_let_1: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
@@ -613,3 +686,197 @@ issue_4954: {
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5516: {
|
||||
options = {
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
varify: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
console.log(typeof function() {
|
||||
{
|
||||
let a;
|
||||
}
|
||||
{
|
||||
const a = function() {};
|
||||
return a;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log(typeof function() {
|
||||
{
|
||||
const a = function() {};
|
||||
return a;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect_stdout: "function"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5697_1: {
|
||||
options = {
|
||||
if_return: true,
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
varify: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
f();
|
||||
return typeof a;
|
||||
function f() {
|
||||
(function() {
|
||||
for (var k in { foo: 42 }) {
|
||||
const a = k;
|
||||
console.log(a);
|
||||
}
|
||||
})();
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
(function() {
|
||||
for (var k in { foo: 42 }) {
|
||||
var a = k;
|
||||
console.log(a);
|
||||
}
|
||||
})();
|
||||
return typeof a;
|
||||
}());
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"undefined",
|
||||
]
|
||||
}
|
||||
|
||||
issue_5697_2: {
|
||||
options = {
|
||||
if_return: true,
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
varify: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
console.log(function() {
|
||||
f();
|
||||
return typeof a;
|
||||
function f() {
|
||||
(function() {
|
||||
for (var k in { foo: 42 }) {
|
||||
let a = k;
|
||||
console.log(a);
|
||||
}
|
||||
})();
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log(function() {
|
||||
(function() {
|
||||
for (var k in { foo: 42 }) {
|
||||
var a = k;
|
||||
console.log(a);
|
||||
}
|
||||
})();
|
||||
return typeof a;
|
||||
}());
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"undefined",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5697_3: {
|
||||
options = {
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
varify: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
f();
|
||||
return typeof a;
|
||||
function f() {
|
||||
(function() {
|
||||
for (var k in { foo: 42 }) {
|
||||
const a = k;
|
||||
console.log(a);
|
||||
}
|
||||
})();
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
(function() {
|
||||
for (var k in { foo: 42 }) {
|
||||
var a = k;
|
||||
console.log(a);
|
||||
}
|
||||
})();
|
||||
return typeof a;
|
||||
}());
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"undefined",
|
||||
]
|
||||
}
|
||||
|
||||
issue_5697_4: {
|
||||
options = {
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
varify: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
console.log(function() {
|
||||
f();
|
||||
return typeof a;
|
||||
function f() {
|
||||
(function() {
|
||||
for (var k in { foo: 42 }) {
|
||||
let a = k;
|
||||
console.log(a);
|
||||
}
|
||||
})();
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log(function() {
|
||||
(function() {
|
||||
for (var k in { foo: 42 }) {
|
||||
var a = k;
|
||||
console.log(a);
|
||||
}
|
||||
})();
|
||||
return typeof a;
|
||||
}());
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"undefined",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
@@ -896,7 +896,7 @@ dont_inline_nested: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
drop_body: {
|
||||
drop_body_1: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
yields: true,
|
||||
@@ -907,7 +907,28 @@ drop_body: {
|
||||
})([ console.log("baz") ]);
|
||||
}
|
||||
expect: {
|
||||
[ [ , [].e = console.log("foo") ] ] = [ [ console.log("baz") ] ];
|
||||
void ([ [ , [][0] = console.log("foo") ] ] = [ [ console.log("baz") ] ]);
|
||||
}
|
||||
expect_stdout: [
|
||||
"baz",
|
||||
"foo",
|
||||
]
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
drop_body_2: {
|
||||
options = {
|
||||
passes: 2,
|
||||
side_effects: true,
|
||||
yields: true,
|
||||
}
|
||||
input: {
|
||||
(function*([ , a = console.log("foo") ]) {
|
||||
console.log("bar");
|
||||
})([ console.log("baz") ]);
|
||||
}
|
||||
expect: {
|
||||
[ [ , [][0] = console.log("foo") ] ] = [ [ console.log("baz") ] ];
|
||||
}
|
||||
expect_stdout: [
|
||||
"baz",
|
||||
@@ -1183,6 +1204,35 @@ issue_4641_2: {
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_4641_3: {
|
||||
options = {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
console.log(typeof async function*() {
|
||||
try {
|
||||
return void "FAIL";
|
||||
} finally {
|
||||
console.log("PASS");
|
||||
}
|
||||
}().next().then);
|
||||
}
|
||||
expect: {
|
||||
console.log(typeof async function*() {
|
||||
try {
|
||||
return void "FAIL";
|
||||
} finally {
|
||||
console.log("PASS");
|
||||
}
|
||||
}().next().then);
|
||||
}
|
||||
expect_stdout: [
|
||||
"function",
|
||||
"PASS",
|
||||
]
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_4769_1: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
@@ -1336,7 +1386,7 @@ issue_5076_1: {
|
||||
expect: {
|
||||
var a;
|
||||
console.log("PASS"),
|
||||
a = 42["a"];
|
||||
a = 42..a;
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
@@ -1467,6 +1517,80 @@ issue_5385_2: {
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_5385_3: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(async function*() {
|
||||
return function() {
|
||||
try {
|
||||
throw console.log("foo");
|
||||
} catch (e) {
|
||||
return console.log("bar");
|
||||
}
|
||||
}();
|
||||
})().next();
|
||||
console.log("moo");
|
||||
}
|
||||
expect: {
|
||||
(async function*() {
|
||||
try {
|
||||
throw console.log("foo");
|
||||
} catch (e) {
|
||||
return console.log("bar");
|
||||
}
|
||||
return void 0;
|
||||
})().next();
|
||||
console.log("moo");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"moo",
|
||||
]
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_5385_4: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(async function*() {
|
||||
return async function() {
|
||||
try {
|
||||
return {
|
||||
then(resolve) {
|
||||
resolve(console.log("FAIL"));
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
return "PASS";
|
||||
}
|
||||
}();
|
||||
})().next().then(o => console.log(o.value, o.done));
|
||||
}
|
||||
expect: {
|
||||
(async function*() {
|
||||
return async function() {
|
||||
try {
|
||||
return {
|
||||
then(resolve) {
|
||||
resolve(console.log("FAIL"));
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
return "PASS";
|
||||
}
|
||||
}();
|
||||
})().next().then(o => console.log(o.value, o.done));
|
||||
}
|
||||
expect_stdout: "PASS true"
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_5425: {
|
||||
options = {
|
||||
assignments: true,
|
||||
@@ -1562,3 +1686,564 @@ issue_5506: {
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5526: {
|
||||
options = {
|
||||
inline: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(async function*() {
|
||||
try {
|
||||
return function() {
|
||||
while (console.log("foo"));
|
||||
}();
|
||||
} finally {
|
||||
console.log("bar");
|
||||
}
|
||||
})().next();
|
||||
console.log("baz");
|
||||
}
|
||||
expect: {
|
||||
(async function*() {
|
||||
try {
|
||||
while (console.log("foo"));
|
||||
return void 0;
|
||||
} finally {
|
||||
console.log("bar");
|
||||
}
|
||||
})().next();
|
||||
console.log("baz");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"baz",
|
||||
"bar",
|
||||
]
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_5576: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(async function*() {
|
||||
try {
|
||||
(function() {
|
||||
while (console.log("foo"));
|
||||
})();
|
||||
} finally {
|
||||
console.log("bar");
|
||||
}
|
||||
})().next();
|
||||
console.log("baz");
|
||||
}
|
||||
expect: {
|
||||
(async function*() {
|
||||
try {
|
||||
while (console.log("foo"));
|
||||
} finally {
|
||||
console.log("bar");
|
||||
}
|
||||
})().next();
|
||||
console.log("baz");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_5663: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var [ , a ] = function*() {
|
||||
console.log("foo");
|
||||
yield console.log("bar");
|
||||
console.log("baz");
|
||||
yield console.log("moo");
|
||||
console.log("moz");
|
||||
yield FAIL;
|
||||
}();
|
||||
}
|
||||
expect: {
|
||||
var [ , , ] = function*() {
|
||||
console.log("foo");
|
||||
yield console.log("bar");
|
||||
console.log("baz");
|
||||
yield console.log("moo");
|
||||
console.log("moz");
|
||||
yield FAIL;
|
||||
}();
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
"moo",
|
||||
]
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5679_1: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL";
|
||||
async function* f(b) {
|
||||
try {
|
||||
if (b)
|
||||
return;
|
||||
else
|
||||
return;
|
||||
} finally {
|
||||
a = "PASS";
|
||||
}
|
||||
}
|
||||
f().next();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "FAIL";
|
||||
async function* f(b) {
|
||||
try {
|
||||
b;
|
||||
return;
|
||||
} finally {
|
||||
a = "PASS";
|
||||
}
|
||||
}
|
||||
f().next();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_5679_2: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL";
|
||||
async function* f(b) {
|
||||
try {
|
||||
if (b)
|
||||
return undefined;
|
||||
else
|
||||
return;
|
||||
} finally {
|
||||
a = "PASS";
|
||||
}
|
||||
}
|
||||
f().next();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "FAIL";
|
||||
async function* f(b) {
|
||||
try {
|
||||
if (b)
|
||||
return void 0;
|
||||
return;
|
||||
} finally {
|
||||
a = "PASS";
|
||||
}
|
||||
}
|
||||
f().next();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_5679_3: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL";
|
||||
async function* f(b) {
|
||||
try {
|
||||
if (b)
|
||||
return;
|
||||
else
|
||||
return undefined;
|
||||
} finally {
|
||||
a = "PASS";
|
||||
}
|
||||
}
|
||||
f(42).next();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "FAIL";
|
||||
async function* f(b) {
|
||||
try {
|
||||
if (b)
|
||||
return;
|
||||
return void 0;
|
||||
} finally {
|
||||
a = "PASS";
|
||||
}
|
||||
}
|
||||
f(42).next();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_5679_4: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
async function* f(b) {
|
||||
try {
|
||||
if (b)
|
||||
return undefined;
|
||||
else
|
||||
return undefined;
|
||||
} finally {
|
||||
a = "FAIL";
|
||||
}
|
||||
}
|
||||
f(null).next();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
async function* f(b) {
|
||||
try {
|
||||
return b, void 0;
|
||||
} finally {
|
||||
a = "FAIL";
|
||||
}
|
||||
}
|
||||
f(null).next();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_5679_5: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL";
|
||||
async function* f(b) {
|
||||
try {
|
||||
if (b)
|
||||
return console;
|
||||
else
|
||||
return;
|
||||
} finally {
|
||||
a = "PASS";
|
||||
}
|
||||
}
|
||||
f().next();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "FAIL";
|
||||
async function* f(b) {
|
||||
try {
|
||||
if (b)
|
||||
return console;
|
||||
return;
|
||||
} finally {
|
||||
a = "PASS";
|
||||
}
|
||||
}
|
||||
f().next();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_5679_6: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
async function* f(b) {
|
||||
try {
|
||||
if (b)
|
||||
return;
|
||||
else
|
||||
return console;
|
||||
} finally {
|
||||
a = "FAIL";
|
||||
}
|
||||
}
|
||||
f().next();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
async function* f(b) {
|
||||
try {
|
||||
if (!b)
|
||||
return console;
|
||||
} finally {
|
||||
a = "FAIL";
|
||||
}
|
||||
}
|
||||
f().next();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_5684: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
(async function*() {
|
||||
switch (42) {
|
||||
default:
|
||||
if (console.log("PASS"))
|
||||
return;
|
||||
return null;
|
||||
case false:
|
||||
}
|
||||
})().next();
|
||||
}
|
||||
expect: {
|
||||
(async function*() {
|
||||
switch (42) {
|
||||
default:
|
||||
return console.log("PASS") ? void 0 : null;
|
||||
case false:
|
||||
}
|
||||
})().next();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_5707_1: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
yields: true,
|
||||
}
|
||||
input: {
|
||||
var a, b;
|
||||
function* f(c = (b = 42, console.log("PASS"))) {}
|
||||
b = f();
|
||||
}
|
||||
expect: {
|
||||
(function(c = console.log("PASS")) {})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5707_2: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
yields: true,
|
||||
}
|
||||
input: {
|
||||
var a, b;
|
||||
function* f(c = (b = 42, console.log("PASS"))) {}
|
||||
b = f();
|
||||
}
|
||||
expect: {
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5710: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
(async function*() {
|
||||
try {
|
||||
switch (42) {
|
||||
case 42:
|
||||
{
|
||||
if (console.log("PASS"))
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} finally {}
|
||||
})().next();
|
||||
}
|
||||
expect: {
|
||||
(async function*() {
|
||||
try {
|
||||
switch (42) {
|
||||
case 42:
|
||||
if (console.log("PASS"))
|
||||
return;
|
||||
return null;
|
||||
break;
|
||||
}
|
||||
} finally {}
|
||||
})().next();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_5749_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
yields: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
function* f() {}
|
||||
a = f(new function() {
|
||||
var b = a |= 0, c = a += console.log("PASS");
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
(function() {})(function() {
|
||||
console.log("PASS");
|
||||
}());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5749_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
yields: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
function* f() {}
|
||||
a = f(new function() {
|
||||
var b = a |= 0, c = a += console.log("PASS");
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5754: {
|
||||
options = {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
async function* f(a, b) {
|
||||
try {
|
||||
if (a)
|
||||
return void 0;
|
||||
} finally {
|
||||
console.log(b);
|
||||
}
|
||||
}
|
||||
f(42, "foo").next();
|
||||
f(null, "bar").next();
|
||||
console.log("baz");
|
||||
}
|
||||
expect: {
|
||||
async function* f(a, b) {
|
||||
try {
|
||||
if (a)
|
||||
return void 0;
|
||||
} finally {
|
||||
console.log(b);
|
||||
}
|
||||
}
|
||||
f(42, "foo").next();
|
||||
f(null, "bar").next();
|
||||
console.log("baz");
|
||||
}
|
||||
expect_stdout: [
|
||||
"bar",
|
||||
"baz",
|
||||
"foo",
|
||||
]
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_5842: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL";
|
||||
(async function*() {
|
||||
(function() {
|
||||
try {
|
||||
try {
|
||||
return console;
|
||||
} finally {
|
||||
a = "PASS";
|
||||
}
|
||||
} catch (e) {}
|
||||
FAIL;
|
||||
})();
|
||||
})().next();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "FAIL";
|
||||
(async function*() {
|
||||
(function() {
|
||||
try {
|
||||
try {
|
||||
return console;
|
||||
} finally {
|
||||
a = "PASS";
|
||||
}
|
||||
} catch (e) {}
|
||||
FAIL;
|
||||
})();
|
||||
})().next();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
@@ -38,4 +38,4 @@ var _require = require("bar"), foo = _require.foo;
|
||||
var _require2 = require("world"), hello = _require2.hello;
|
||||
|
||||
foo.x.apply(foo, _toConsumableArray(foo.y(hello.z)));
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImlucHV0LmpzIl0sInNvdXJjZXNDb250ZW50IjpbImNvbnN0IHtmb299ID0gcmVxdWlyZShcImJhclwiKTtcbmNvbnN0IHtoZWxsb30gPSByZXF1aXJlKFwid29ybGRcIik7XG5cbmZvby54KC4uLmZvby55KGhlbGxvLnopKTtcbiJdLCJuYW1lcyI6WyJyZXF1aXJlIiwiZm9vIiwiaGVsbG8iLCJ4IiwiYXBwbHkiLCJfdG9Db25zdW1hYmxlQXJyYXkiLCJ5IiwieiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7ZUFBY0EsUUFBUSxRQUFmQyxNLFNBQUFBOztBLGdCQUNTRCxRQUFRLFVBQWpCRSxRLFVBQUFBOztBQUVQRCxJQUFJRSxFQUFKQyxNQUFBSCxLQUFHSSxtQkFBTUosSUFBSUssRUFBRUosTUFBTUsifQ==
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImlucHV0LmpzIl0sInNvdXJjZXNDb250ZW50IjpbImNvbnN0IHtmb299ID0gcmVxdWlyZShcImJhclwiKTtcbmNvbnN0IHtoZWxsb30gPSByZXF1aXJlKFwid29ybGRcIik7XG5cbmZvby54KC4uLmZvby55KGhlbGxvLnopKTtcbiJdLCJuYW1lcyI6WyJyZXF1aXJlIiwiZm9vIiwiaGVsbG8iLCJ4IiwiYXBwbHkiLCJfdG9Db25zdW1hYmxlQXJyYXkiLCJ5IiwieiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7ZUFBY0EsUUFBUSxLQUFELEdBQWRDLE0sU0FBQUE7O0EsZ0JBQ1NELFFBQVEsT0FBRCxHQUFoQkUsUSxVQUFBQTs7QUFFUEQsSUFBSUUsRUFBSkMsTUFBQUgsS0FBR0ksbUJBQU1KLElBQUlLLEVBQUVKLE1BQU1LLENBQVosQ0FBTixDQUFBIn0=
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
console.log(3);
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIl0sInNvdXJjZXNDb250ZW50IjpbImNsYXNzIEZvbyB7IGNvbnN0cnVjdG9yKCl7Y29uc29sZS5sb2coMSsyKTt9IH0gbmV3IEZvbygpO1xuIl0sIm5hbWVzIjpbImNvbnNvbGUiLCJsb2ciXSwibWFwcGluZ3MiOiJBQUEwQkEsUUFBUUMsSUFBSSJ9
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIl0sInNvdXJjZXNDb250ZW50IjpbImNsYXNzIEZvbyB7IGNvbnN0cnVjdG9yKCl7Y29uc29sZS5sb2coMSsyKTt9IH0gbmV3IEZvbygpO1xuIl0sIm5hbWVzIjpbImNvbnNvbGUiLCJsb2ciXSwibWFwcGluZ3MiOiJBQUEwQkEsUUFBUUMsSUFBSSxDQUFHIn0=
|
||||
|
||||
@@ -2,4 +2,4 @@ function test(a){
|
||||
"aaaaaaaaaaaaaaaa";
|
||||
a(err,data),a(err,
|
||||
data)}
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjAiXSwibmFtZXMiOlsidGVzdCIsImNhbGxiYWNrIiwiZXJyIiwiZGF0YSJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0E7SEFBS0M7QUFFVkE7aEJBQVNDLElBQUtDLE1BQ2RGLEVBQVNDLElBQUtDIn0=
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjAiXSwibmFtZXMiOlsidGVzdCIsImNhbGxiYWNrIiwiZXJyIiwiZGF0YSJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0E7SEFBS0MsR0FDVjtBQUNBQTtoQkFBU0MsSUFBS0MsSUFBSSxFQUNsQkYsRUFBU0MsSUFBS0MsSUFBSSxDQUN0QiJ9
|
||||
@@ -1,2 +1,2 @@
|
||||
console.log(3);
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIl0sInNvdXJjZXNDb250ZW50IjpbImNsYXNzIEZvbyB7IGNvbnN0cnVjdG9yKCl7Y29uc29sZS5sb2coMSsyKTt9IH0gbmV3IEZvbygpO1xuIl0sIm5hbWVzIjpbImNvbnNvbGUiLCJsb2ciXSwibWFwcGluZ3MiOiJBQUEwQkEsUUFBUUMsSUFBSSJ9
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIl0sInNvdXJjZXNDb250ZW50IjpbImNsYXNzIEZvbyB7IGNvbnN0cnVjdG9yKCl7Y29uc29sZS5sb2coMSsyKTt9IH0gbmV3IEZvbygpO1xuIl0sIm5hbWVzIjpbImNvbnNvbGUiLCJsb2ciXSwibWFwcGluZ3MiOiJBQUEwQkEsUUFBUUMsSUFBSSxDQUFHIn0=
|
||||
|
||||
@@ -1,16 +1,10 @@
|
||||
// (beautified)
|
||||
var b = 0;
|
||||
|
||||
var expr2 = (0 - 1 - .1 - .1).toString();
|
||||
|
||||
for (var key2 in expr2) {
|
||||
--b;
|
||||
}
|
||||
|
||||
console.log(b);
|
||||
// output: -19
|
||||
console.log(expr2);
|
||||
// output: -1.2000000000000002
|
||||
//
|
||||
// minify: -4
|
||||
// minify: -1.2
|
||||
//
|
||||
// options: {
|
||||
// "compress": {
|
||||
|
||||
@@ -14,7 +14,7 @@ if (typeof phantom == "undefined") {
|
||||
args.splice(debug, 1);
|
||||
debug = true;
|
||||
}
|
||||
if (!args.length) args.push("-mcb", "beautify=false,webkit");
|
||||
if (!args.length) args.push("-mcO", "webkit");
|
||||
args.unshift("bin/uglifyjs");
|
||||
args.push("--validate", "--timings");
|
||||
var child_process = require("child_process");
|
||||
@@ -62,7 +62,11 @@ if (typeof phantom == "undefined") {
|
||||
var cmd = process.platform == "win32" ? "npm.cmd" : "npm";
|
||||
|
||||
function npm(args, done) {
|
||||
child_process.spawn(cmd, args, { stdio: [ "ignore", 1, 2 ] }).on("exit", done);
|
||||
args.push("--loglevel=error");
|
||||
child_process.spawn(cmd, args, {
|
||||
shell: true,
|
||||
stdio: [ "ignore", 1, 2 ],
|
||||
}).on("exit", done);
|
||||
}
|
||||
|
||||
(function install() {
|
||||
@@ -72,9 +76,12 @@ if (typeof phantom == "undefined") {
|
||||
"is-my-json-valid@2.20.5",
|
||||
"phantomjs-prebuilt@2.1.14",
|
||||
"--no-audit",
|
||||
"--no-fund",
|
||||
"--no-optional",
|
||||
"--no-save",
|
||||
"--no-strict-ssl",
|
||||
"--no-update-notifier",
|
||||
"--production",
|
||||
], function(code) {
|
||||
if (code) {
|
||||
console.log("npm install failed with code", code);
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
var fs = require("fs");
|
||||
|
||||
var config = {
|
||||
limit: 10000,
|
||||
timeout: function(limit) {
|
||||
this.limit = limit;
|
||||
}
|
||||
this.limit = limit + lag;
|
||||
},
|
||||
};
|
||||
var lag = +process.env["UGLIFY_GITHUB_LAG"] || 0;
|
||||
var tasks = [];
|
||||
var titles = [];
|
||||
config.timeout(10000);
|
||||
describe = function(title, fn) {
|
||||
config = Object.create(config);
|
||||
titles.push(title);
|
||||
@@ -21,10 +22,11 @@ it = function(title, fn) {
|
||||
fn.titles.push(title);
|
||||
tasks.push(fn);
|
||||
};
|
||||
|
||||
fs.readdirSync("test/mocha").filter(function(file) {
|
||||
return /\.js$/.test(file);
|
||||
}).forEach(function(file) {
|
||||
(function(arg) {
|
||||
return arg ? [ arg ] : fs.readdirSync("test/mocha").filter(function(file) {
|
||||
return /\.js$/.test(file);
|
||||
});
|
||||
})(process.argv[2]).forEach(function(file) {
|
||||
require("./mocha/" + file);
|
||||
});
|
||||
|
||||
@@ -66,12 +68,13 @@ process.nextTick(function run() {
|
||||
if (task.length) {
|
||||
task.timeout = function(limit) {
|
||||
clearTimeout(timer);
|
||||
limit += lag;
|
||||
task.limit = limit;
|
||||
timer = setTimeout(function() {
|
||||
raise(new Error("Timed out: exceeds " + limit + "ms"));
|
||||
}, limit);
|
||||
};
|
||||
task.timeout(task.limit);
|
||||
task.timeout(task.limit - lag);
|
||||
process.on("uncaughtException", raise);
|
||||
task.call(task, done);
|
||||
} else {
|
||||
|
||||
@@ -53,6 +53,23 @@ describe("bin/uglifyjs", function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should work with --expression", function(done) {
|
||||
exec([
|
||||
uglifyjscmd,
|
||||
"--expression",
|
||||
"--compress",
|
||||
"--mangle",
|
||||
].join(" "), function(err, stdout) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, "function(n){for(;n(););return 42}(A)\n");
|
||||
done();
|
||||
}).stdin.end([
|
||||
"function(x) {",
|
||||
" while (x()) {}",
|
||||
" return 42;",
|
||||
"}(A)",
|
||||
].join("\n"));
|
||||
});
|
||||
it("Should work with --source-map names=true", function(done) {
|
||||
exec([
|
||||
uglifyjscmd,
|
||||
@@ -69,7 +86,7 @@ describe("bin/uglifyjs", function() {
|
||||
" q: b",
|
||||
"};",
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,",
|
||||
].join("\n")
|
||||
].join("\n");
|
||||
assert.strictEqual(stdout.slice(0, expected.length), expected);
|
||||
var map = JSON.parse(to_ascii(stdout.slice(expected.length).trim()));
|
||||
assert.deepEqual(map.names, [ "obj", "p", "a", "q", "b" ]);
|
||||
@@ -97,7 +114,7 @@ describe("bin/uglifyjs", function() {
|
||||
" q: b",
|
||||
"};",
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,",
|
||||
].join("\n")
|
||||
].join("\n");
|
||||
assert.strictEqual(stdout.slice(0, expected.length), expected);
|
||||
var map = JSON.parse(to_ascii(stdout.slice(expected.length).trim()));
|
||||
assert.deepEqual(map.names, []);
|
||||
@@ -126,7 +143,7 @@ describe("bin/uglifyjs", function() {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, [
|
||||
"var bar=function(){function foo(bar){return bar}return foo}();",
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxJQUdYLE9BQU9DLElBTEQifQ==",
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxHQUNYLENBRUEsT0FBT0MsR0FDVixFQUFFIn0=",
|
||||
"",
|
||||
].join("\n"));
|
||||
done();
|
||||
@@ -189,7 +206,13 @@ describe("bin/uglifyjs", function() {
|
||||
}, 1000);
|
||||
});
|
||||
it("Should work with --keep-fargs (mangle only)", function(done) {
|
||||
var command = uglifyjscmd + ' test/input/issue-1431/sample.js --keep-fargs -m';
|
||||
var command = [
|
||||
uglifyjscmd,
|
||||
"test/input/issue-1431/sample.js",
|
||||
"--keep-fargs",
|
||||
"--mangle",
|
||||
"--no-module",
|
||||
].join(" ");
|
||||
exec(command, function(err, stdout) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, "function f(x){return function(){function n(a){return a*a}return x(n)}}function g(op){return op(1)+op(2)}console.log(f(g)()==5);\n");
|
||||
@@ -197,7 +220,14 @@ describe("bin/uglifyjs", function() {
|
||||
});
|
||||
});
|
||||
it("Should work with --keep-fargs (mangle & compress)", function(done) {
|
||||
var command = uglifyjscmd + ' test/input/issue-1431/sample.js --keep-fargs -m -c';
|
||||
var command = [
|
||||
uglifyjscmd,
|
||||
"test/input/issue-1431/sample.js",
|
||||
"--keep-fargs",
|
||||
"--mangle",
|
||||
"--no-module",
|
||||
"--compress",
|
||||
].join(" ");
|
||||
exec(command, function(err, stdout) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, "function f(x){return function(){return x(function(a){return a*a})}}function g(op){return op(1)+op(2)}console.log(5==f(g)());\n");
|
||||
@@ -205,7 +235,12 @@ describe("bin/uglifyjs", function() {
|
||||
});
|
||||
});
|
||||
it("Should work with keep_fargs under mangler options", function(done) {
|
||||
var command = uglifyjscmd + ' test/input/issue-1431/sample.js -m keep_fargs=true';
|
||||
var command = [
|
||||
uglifyjscmd,
|
||||
"test/input/issue-1431/sample.js",
|
||||
"--mangle", "keep_fargs=true",
|
||||
"--no-module",
|
||||
].join(" ");
|
||||
exec(command, function(err, stdout) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, "function f(x){return function(){function n(a){return a*a}return x(n)}}function g(op){return op(1)+op(2)}console.log(f(g)()==5);\n");
|
||||
@@ -213,7 +248,12 @@ describe("bin/uglifyjs", function() {
|
||||
});
|
||||
});
|
||||
it("Should work with --keep-fnames (mangle only)", function(done) {
|
||||
var command = uglifyjscmd + ' test/input/issue-1431/sample.js --keep-fnames -m';
|
||||
var command = [
|
||||
uglifyjscmd,
|
||||
"test/input/issue-1431/sample.js",
|
||||
"--keep-fnames",
|
||||
"--mangle",
|
||||
].join(" ");
|
||||
exec(command, function(err, stdout) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, "function f(r){return function(){function n(n){return n*n}return r(n)}}function g(n){return n(1)+n(2)}console.log(f(g)()==5);\n");
|
||||
@@ -221,7 +261,14 @@ describe("bin/uglifyjs", function() {
|
||||
});
|
||||
});
|
||||
it("Should work with --keep-fnames (mangle & compress)", function(done) {
|
||||
var command = uglifyjscmd + ' test/input/issue-1431/sample.js --keep-fnames -m -c';
|
||||
var command = [
|
||||
uglifyjscmd,
|
||||
"test/input/issue-1431/sample.js",
|
||||
"--keep-fnames",
|
||||
"--mangle",
|
||||
"--no-module",
|
||||
"--compress",
|
||||
].join(" ");
|
||||
exec(command, function(err, stdout) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, "function f(n){return function(){return n(function n(r){return r*r})}}function g(n){return n(1)+n(2)}console.log(5==f(g)());\n");
|
||||
@@ -313,7 +360,7 @@ describe("bin/uglifyjs", function() {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, [
|
||||
"var bar=function(){function foo(bar){return bar}return foo}();",
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxJQUdYLE9BQU9DLElBTEQifQ==",
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxHQUNYLENBRUEsT0FBT0MsR0FDVixFQUFFIn0=",
|
||||
"",
|
||||
].join("\n"));
|
||||
var stderrLines = stderr.split("\n");
|
||||
@@ -333,7 +380,7 @@ describe("bin/uglifyjs", function() {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, [
|
||||
"var Foo=function Foo(){console.log(1+2)};new Foo;var bar=function(){function foo(bar){return bar}return foo}();",
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIiwidGVzdC9pbnB1dC9pc3N1ZS0xMzIzL3NhbXBsZS5qcyJdLCJuYW1lcyI6WyJGb28iLCJjb25zb2xlIiwibG9nIiwiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFNQSxJQUFJLFNBQUVBLE1BQWNDLFFBQVFDLElBQUksRUFBRSxJQUFPLElBQUlGLElDQW5ELElBQUlHLElBQU0sV0FDTixTQUFTQyxJQUFLRCxLQUNWLE9BQU9BLElBR1gsT0FBT0MsSUFMRCJ9",
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIiwidGVzdC9pbnB1dC9pc3N1ZS0xMzIzL3NhbXBsZS5qcyJdLCJuYW1lcyI6WyJGb28iLCJjb25zb2xlIiwibG9nIiwiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFNQSxJQUFJLFNBQUVBLE1BQWNDLFFBQVFDLElBQUksRUFBRSxDQUFDLENBQUUsRUFBSSxJQUFJRixJQ0FuRCxJQUFJRyxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxHQUNYLENBRUEsT0FBT0MsR0FDVixFQUFFIn0=",
|
||||
"",
|
||||
].join("\n"));
|
||||
var stderrLines = stderr.split("\n");
|
||||
@@ -540,7 +587,11 @@ describe("bin/uglifyjs", function() {
|
||||
});
|
||||
});
|
||||
it("Should throw syntax error (delete x)", function(done) {
|
||||
var command = uglifyjscmd + " test/input/invalid/delete.js";
|
||||
var command = [
|
||||
uglifyjscmd,
|
||||
"test/input/invalid/delete.js",
|
||||
"--no-module",
|
||||
].join(" ");
|
||||
exec(command, function(err, stdout, stderr) {
|
||||
assert.ok(err);
|
||||
assert.strictEqual(stdout, "");
|
||||
@@ -554,7 +605,11 @@ describe("bin/uglifyjs", function() {
|
||||
});
|
||||
});
|
||||
it("Should throw syntax error (function g(arguments))", function(done) {
|
||||
var command = uglifyjscmd + " test/input/invalid/function_1.js";
|
||||
var command = [
|
||||
uglifyjscmd,
|
||||
"test/input/invalid/function_1.js",
|
||||
"--no-module",
|
||||
].join(" ");
|
||||
exec(command, function(err, stdout, stderr) {
|
||||
assert.ok(err);
|
||||
assert.strictEqual(stdout, "");
|
||||
@@ -568,7 +623,11 @@ describe("bin/uglifyjs", function() {
|
||||
});
|
||||
});
|
||||
it("Should throw syntax error (function eval())", function(done) {
|
||||
var command = uglifyjscmd + " test/input/invalid/function_2.js";
|
||||
var command = [
|
||||
uglifyjscmd,
|
||||
"test/input/invalid/function_2.js",
|
||||
"--no-module",
|
||||
].join(" ");
|
||||
exec(command, function(err, stdout, stderr) {
|
||||
assert.ok(err);
|
||||
assert.strictEqual(stdout, "");
|
||||
@@ -582,7 +641,11 @@ describe("bin/uglifyjs", function() {
|
||||
});
|
||||
});
|
||||
it("Should throw syntax error (iife arguments())", function(done) {
|
||||
var command = uglifyjscmd + " test/input/invalid/function_3.js";
|
||||
var command = [
|
||||
uglifyjscmd,
|
||||
"test/input/invalid/function_3.js",
|
||||
"--no-module",
|
||||
].join(" ");
|
||||
exec(command, function(err, stdout, stderr) {
|
||||
assert.ok(err);
|
||||
assert.strictEqual(stdout, "");
|
||||
@@ -596,7 +659,11 @@ describe("bin/uglifyjs", function() {
|
||||
});
|
||||
});
|
||||
it("Should throw syntax error (catch (eval))", function(done) {
|
||||
var command = uglifyjscmd + " test/input/invalid/try.js";
|
||||
var command = [
|
||||
uglifyjscmd,
|
||||
"test/input/invalid/try.js",
|
||||
"--no-module",
|
||||
].join(" ");
|
||||
exec(command, function(err, stdout, stderr) {
|
||||
assert.ok(err);
|
||||
assert.strictEqual(stdout, "");
|
||||
@@ -610,7 +677,11 @@ describe("bin/uglifyjs", function() {
|
||||
});
|
||||
});
|
||||
it("Should throw syntax error (var eval)", function(done) {
|
||||
var command = uglifyjscmd + " test/input/invalid/var.js";
|
||||
var command = [
|
||||
uglifyjscmd,
|
||||
"test/input/invalid/var.js",
|
||||
"--no-module",
|
||||
].join(" ");
|
||||
exec(command, function(err, stdout, stderr) {
|
||||
assert.ok(err);
|
||||
assert.strictEqual(stdout, "");
|
||||
@@ -624,7 +695,11 @@ describe("bin/uglifyjs", function() {
|
||||
});
|
||||
});
|
||||
it("Should throw syntax error (var { eval })", function(done) {
|
||||
var command = uglifyjscmd + " test/input/invalid/destructured_var.js";
|
||||
var command = [
|
||||
uglifyjscmd,
|
||||
"test/input/invalid/destructured_var.js",
|
||||
"--no-module",
|
||||
].join(" ");
|
||||
exec(command, function(err, stdout, stderr) {
|
||||
assert.ok(err);
|
||||
assert.strictEqual(stdout, "");
|
||||
@@ -774,7 +849,7 @@ describe("bin/uglifyjs", function() {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, [
|
||||
'"use strict";var foo=function foo(x){return"foo "+x};console.log(foo("bar"));',
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImluZGV4LmpzIl0sIm5hbWVzIjpbImZvbyIsIngiLCJjb25zb2xlIiwibG9nIl0sIm1hcHBpbmdzIjoiYUFBQSxJQUFJQSxJQUFNLFNBQU5BLElBQU1DLEdBQUEsTUFBSyxPQUFTQSxHQUN4QkMsUUFBUUMsSUFBSUgsSUFBSSJ9",
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImluZGV4LmpzIl0sIm5hbWVzIjpbImZvbyIsIngiLCJjb25zb2xlIiwibG9nIl0sIm1hcHBpbmdzIjoiYUFBQSxJQUFJQSxJQUFNLFNBQU5BLElBQU1DLEdBQUEsTUFBSyxPQUFTQSxDQUFkLEVBQ1ZDLFFBQVFDLElBQUlILElBQUksS0FBSixDQUFaIn0=",
|
||||
""
|
||||
].join("\n"));
|
||||
done();
|
||||
@@ -790,14 +865,15 @@ describe("bin/uglifyjs", function() {
|
||||
var command = [
|
||||
uglifyjscmd,
|
||||
"test/input/issue-2310/input.js",
|
||||
"-c",
|
||||
"--compress",
|
||||
"--no-module",
|
||||
"--source-map", "url=inline",
|
||||
].join(" ");
|
||||
exec(command, function(err, stdout, stderr) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, [
|
||||
'function foo(){return function(){console.log("PASS")}}foo()();',
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMjMxMC9pbnB1dC5qcyJdLCJuYW1lcyI6WyJmb28iLCJjb25zb2xlIiwibG9nIiwiZiJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsTUFDTCxPQUFPLFdBQ0hDLFFBQVFDLElBQUksU0FLUkYsS0FDUkcifQ==",
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMjMxMC9pbnB1dC5qcyJdLCJuYW1lcyI6WyJmb28iLCJjb25zb2xlIiwibG9nIl0sIm1hcHBpbmdzIjoiQUFBQSxTQUFTQSxNQUNMLE9BQU8sV0FDSEMsUUFBUUMsSUFBSSxNQUFNLENBQ3RCLENBQ0osQ0FHWUYsSUFBSSxFQUNWIn0=",
|
||||
""
|
||||
].join("\n"));
|
||||
done();
|
||||
@@ -823,7 +899,12 @@ describe("bin/uglifyjs", function() {
|
||||
});
|
||||
});
|
||||
it("Should work with --mangle reserved=[]", function(done) {
|
||||
var command = uglifyjscmd + " test/input/issue-505/input.js -m reserved=[callback]";
|
||||
var command = [
|
||||
uglifyjscmd,
|
||||
"test/input/issue-505/input.js",
|
||||
"--mangle", "reserved=[callback]",
|
||||
"--no-module",
|
||||
].join(" ");
|
||||
exec(command, function(err, stdout) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, 'function test(callback){"aaaaaaaaaaaaaaaa";callback(err,data);callback(err,data)}\n');
|
||||
@@ -831,7 +912,12 @@ describe("bin/uglifyjs", function() {
|
||||
});
|
||||
});
|
||||
it("Should work with --mangle reserved=false", function(done) {
|
||||
var command = uglifyjscmd + " test/input/issue-505/input.js -m reserved=false";
|
||||
var command = [
|
||||
uglifyjscmd,
|
||||
"test/input/issue-505/input.js",
|
||||
"--mangle", "reserved=false",
|
||||
"--no-module",
|
||||
].join(" ");
|
||||
exec(command, function(err, stdout) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, 'function test(a){"aaaaaaaaaaaaaaaa";a(err,data);a(err,data)}\n');
|
||||
@@ -848,7 +934,12 @@ describe("bin/uglifyjs", function() {
|
||||
});
|
||||
});
|
||||
it("Should work with mangle.properties.regex from --config-file", function(done) {
|
||||
var command = uglifyjscmd + " test/input/issue-3315/input.js --config-file test/input/issue-3315/config.json";
|
||||
var command = [
|
||||
uglifyjscmd,
|
||||
"test/input/issue-3315/input.js",
|
||||
"--config-file", "test/input/issue-3315/config.json",
|
||||
"--no-module",
|
||||
].join(" ");
|
||||
exec(command, function(err, stdout) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, 'function f(){"aaaaaaaaaa";var a={prop:1,t:2};return a.prop+a.t}\n');
|
||||
@@ -865,7 +956,12 @@ describe("bin/uglifyjs", function() {
|
||||
});
|
||||
});
|
||||
it("Should work with explicit --rename", function(done) {
|
||||
var command = uglifyjscmd + " test/input/rename/input.js --rename";
|
||||
var command = [
|
||||
uglifyjscmd,
|
||||
"test/input/rename/input.js",
|
||||
"--no-module",
|
||||
"--rename",
|
||||
].join(" ");
|
||||
exec(command, function(err, stdout, stderr) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, "function f(a){return b(a);function b(c){return c+c}}\n");
|
||||
@@ -873,7 +969,14 @@ describe("bin/uglifyjs", function() {
|
||||
});
|
||||
});
|
||||
it("Should work with explicit --no-rename", function(done) {
|
||||
var command = uglifyjscmd + " test/input/rename/input.js -mc passes=2 --no-rename";
|
||||
var command = [
|
||||
uglifyjscmd,
|
||||
"test/input/rename/input.js",
|
||||
"--compress", "passes=2",
|
||||
"--mangle",
|
||||
"--no-module",
|
||||
"--no-rename",
|
||||
].join(" ");
|
||||
exec(command, function(err, stdout, stderr) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, "function f(n){return function(n){return n+n}(n)}\n");
|
||||
@@ -881,7 +984,13 @@ describe("bin/uglifyjs", function() {
|
||||
});
|
||||
});
|
||||
it("Should work with implicit --rename", function(done) {
|
||||
var command = uglifyjscmd + " test/input/rename/input.js -mc passes=2";
|
||||
var command = [
|
||||
uglifyjscmd,
|
||||
"test/input/rename/input.js",
|
||||
"--compress", "passes=2",
|
||||
"--mangle",
|
||||
"--no-module",
|
||||
].join(" ");
|
||||
exec(command, function(err, stdout, stderr) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, "function f(n){return n+n}\n");
|
||||
@@ -889,7 +998,12 @@ describe("bin/uglifyjs", function() {
|
||||
});
|
||||
});
|
||||
it("Should work with implicit --no-rename", function(done) {
|
||||
var command = uglifyjscmd + " test/input/rename/input.js -c passes=2";
|
||||
var command = [
|
||||
uglifyjscmd,
|
||||
"test/input/rename/input.js",
|
||||
"--compress", "passes=2",
|
||||
"--no-module",
|
||||
].join(" ");
|
||||
exec(command, function(err, stdout, stderr) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, "function f(x){return function(x){return x+x}(x)}\n");
|
||||
@@ -954,12 +1068,7 @@ describe("bin/uglifyjs", function() {
|
||||
]).join("\n");
|
||||
exec(uglifyjscmd + " -mc", function(err, stdout) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, [
|
||||
"console.log(function(){",
|
||||
"var p={p:25},n={p:121},o={p:1024};",
|
||||
"return p.p+n.p+o.p",
|
||||
"}());\n",
|
||||
].join(""));
|
||||
assert.strictEqual(stdout, "console.log(function(){var p={p:25},n={p:121},o={p:1024};return p.p+n.p+o.p}());\n");
|
||||
assert.strictEqual(run_code(stdout), run_code(code));
|
||||
done();
|
||||
}).stdin.end(code);
|
||||
|
||||
@@ -400,7 +400,7 @@ describe("comments", function() {
|
||||
assert.strictEqual(ast.print_to_string({comments: "all"}), "/*!test1*/\n/*test2*/\n//!test3\n//test4\n//test5\n//!test6\n//test7\n//!test8");
|
||||
});
|
||||
|
||||
it("Should be able to filter commments with the 'some' option", function() {
|
||||
it("Should be able to filter comments with the 'some' option", function() {
|
||||
var ast = UglifyJS.parse("// foo\n/*@preserve*/\n// bar\n/*@license*/\n//@license with the wrong comment type\n/*@cc_on something*/");
|
||||
assert.strictEqual(ast.print_to_string({comments: "some"}), "/*@preserve*/\n/*@license*/\n/*@cc_on something*/");
|
||||
});
|
||||
@@ -476,7 +476,9 @@ describe("comments", function() {
|
||||
for (var i = 1; i <= 5000; ++i) js += "// " + i + "\n";
|
||||
for (; i <= 10000; ++i) js += "/* " + i + " */ /**/";
|
||||
js += "x; }";
|
||||
var result = UglifyJS.minify(js, { mangle: false });
|
||||
var result = UglifyJS.minify(js, {
|
||||
mangle: false,
|
||||
});
|
||||
assert.strictEqual(result.code, "function lots_of_comments(x){return 7-x}");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -348,7 +348,7 @@ describe("Directives", function() {
|
||||
'"use strict";doSomething("foo");'
|
||||
],
|
||||
[
|
||||
// Nothing gets optimised in the compressor because "use asm" is the first statement
|
||||
// Nothing gets optimized in the compressor because "use asm" is the first statement
|
||||
'"use asm";"use\\x20strict";1+1;',
|
||||
'"use asm";"use\\x20strict";1+1;'
|
||||
],
|
||||
@@ -373,7 +373,9 @@ describe("Directives", function() {
|
||||
'function f(){}'
|
||||
],
|
||||
].forEach(function(test) {
|
||||
var result = UglifyJS.minify(test[0]);
|
||||
var result = UglifyJS.minify(test[0], {
|
||||
module: false,
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
assert.strictEqual(result.code, test[1], test[0]);
|
||||
});
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
var acorn = require("acorn");
|
||||
var assert = require("assert");
|
||||
var UglifyJS = require("../node");
|
||||
|
||||
@@ -25,6 +26,7 @@ describe("export", function() {
|
||||
"export { * };",
|
||||
"export { * as A };",
|
||||
"export { 42 as A };",
|
||||
"export { 'A' as B };",
|
||||
"export { A as B-C };",
|
||||
"export { default as A };",
|
||||
].forEach(function(code) {
|
||||
@@ -51,8 +53,11 @@ describe("export", function() {
|
||||
it("Should reject invalid `export ... from ...` statement syntax", function() {
|
||||
[
|
||||
"export from 'path';",
|
||||
"export A from 'path';",
|
||||
"export * from `path`;",
|
||||
"export 'A' from 'path';",
|
||||
"export A as B from 'path';",
|
||||
"export 'A' as B from 'path';",
|
||||
"export default from 'path';",
|
||||
"export { A }, B from 'path';",
|
||||
"export * as A, B from 'path';",
|
||||
@@ -68,4 +73,109 @@ describe("export", function() {
|
||||
}, code);
|
||||
});
|
||||
});
|
||||
it("Should reject `export` statement not under top-level scope", function() {
|
||||
[
|
||||
"{ export {}; }",
|
||||
"if (0) export var A;",
|
||||
"function f() { export default 42; }",
|
||||
].forEach(function(code) {
|
||||
assert.throws(function() {
|
||||
UglifyJS.parse(code);
|
||||
}, function(e) {
|
||||
return e instanceof UglifyJS.JS_Parse_Error;
|
||||
}, code);
|
||||
});
|
||||
});
|
||||
it("Should compare `export` statements correctly", function() {
|
||||
var stats = {
|
||||
Declaration: [
|
||||
"export let A;",
|
||||
"export const A = 42;",
|
||||
"export var { A, B: [] } = C;",
|
||||
"export function A() { return B(A); }",
|
||||
"export async function* A({}, ...[]) { return B(A); }",
|
||||
],
|
||||
Default: [
|
||||
"export default 42;",
|
||||
"export default A => A(B);",
|
||||
"export default class A extends B {}",
|
||||
"export default (class A extends B {});",
|
||||
"export default class A { static C = 42; }",
|
||||
"export default class A extends B { static C = 42; }",
|
||||
],
|
||||
Foreign: [
|
||||
"export * from 'path';",
|
||||
"export {} from 'path';",
|
||||
"export * as A from 'path';",
|
||||
"export { default } from 'path';",
|
||||
"export { A, B as C } from 'path';",
|
||||
"export { A, default as C } from 'path';",
|
||||
],
|
||||
References: [
|
||||
"export {};",
|
||||
"export { A };",
|
||||
"export { A as B };",
|
||||
"export { A, B as C };",
|
||||
"export { A as default };",
|
||||
],
|
||||
};
|
||||
for (var k in stats) stats[k].forEach(function(c, i) {
|
||||
var s = UglifyJS.parse(c);
|
||||
assert.ok(s instanceof UglifyJS.AST_Toplevel, c);
|
||||
assert.strictEqual(s.body.length, 1, c);
|
||||
assert.strictEqual(s.body[0].TYPE, "Export" + k, c);
|
||||
for (var l in stats) stats[l].forEach(function(d, j) {
|
||||
var t = UglifyJS.parse(d);
|
||||
assert.ok(t instanceof UglifyJS.AST_Toplevel, d);
|
||||
assert.strictEqual(t.body.length, 1, d);
|
||||
assert.strictEqual(t.body[0].TYPE, "Export" + l, d);
|
||||
assert.strictEqual(s.equals(t), k === l && i === j, c + "\n" + d);
|
||||
});
|
||||
});
|
||||
});
|
||||
it("Should interoperate with ESTree correctly", function() {
|
||||
[
|
||||
"export var A = 42;",
|
||||
"export default (class A {});",
|
||||
"var A; export { A as '42' };",
|
||||
"export { '42' } from 'path';",
|
||||
"export * as '42' from 'path';",
|
||||
].forEach(function(code) {
|
||||
var ast = UglifyJS.parse(code);
|
||||
try {
|
||||
var spidermonkey = ast.to_mozilla_ast();
|
||||
} catch (ex) {
|
||||
assert.fail("[to_mozilla_ast] " + ex.stack);
|
||||
}
|
||||
try {
|
||||
var ast2 = UglifyJS.AST_Node.from_mozilla_ast(spidermonkey);
|
||||
} catch (ex) {
|
||||
assert.fail("[from_mozilla_ast] " + ex.stack);
|
||||
}
|
||||
assert.strictEqual(ast2.print_to_string(), ast.print_to_string(), [
|
||||
"spidermonkey:",
|
||||
ast.print_to_string(),
|
||||
ast2.print_to_string(),
|
||||
].join("\n"));
|
||||
try {
|
||||
var acorn_est = acorn.parse(code, {
|
||||
ecmaVersion: "latest",
|
||||
locations: true,
|
||||
sourceType: "module",
|
||||
});
|
||||
} catch (ex) {
|
||||
assert.fail("[acorn.parse] " + ex.stack);
|
||||
}
|
||||
try {
|
||||
var ast3 = UglifyJS.AST_Node.from_mozilla_ast(acorn_est);
|
||||
} catch (ex) {
|
||||
assert.fail("[from_acorn] " + ex.stack);
|
||||
}
|
||||
assert.strictEqual(ast3.print_to_string(), ast.print_to_string(), [
|
||||
"acorn:",
|
||||
ast.print_to_string(),
|
||||
ast3.print_to_string(),
|
||||
].join("\n"));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,31 +5,44 @@ var path = require("path");
|
||||
describe("bin/uglifyjs with input file globs", function() {
|
||||
var uglifyjscmd = '"' + process.argv[0] + '" bin/uglifyjs';
|
||||
it("bin/uglifyjs with one input file extension glob.", function(done) {
|
||||
var command = uglifyjscmd + ' "test/input/issue-1242/foo.*" -cm';
|
||||
|
||||
var command = [
|
||||
uglifyjscmd,
|
||||
'"test/input/issue-1242/foo.*"',
|
||||
"--compress",
|
||||
"--mangle",
|
||||
"--no-module",
|
||||
].join(" ");
|
||||
exec(command, function(err, stdout) {
|
||||
if (err) throw err;
|
||||
|
||||
assert.strictEqual(stdout, 'var print=console.log.bind(console);function foo(o){print("Foo:",2*o)}\n');
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("bin/uglifyjs with one input file name glob.", function(done) {
|
||||
var command = uglifyjscmd + ' "test/input/issue-1242/b*.es5" -cm';
|
||||
|
||||
var command = [
|
||||
uglifyjscmd,
|
||||
'"test/input/issue-1242/b*.es5"',
|
||||
"--compress",
|
||||
"--mangle",
|
||||
"--no-module",
|
||||
].join(" ");
|
||||
exec(command, function(err, stdout) {
|
||||
if (err) throw err;
|
||||
|
||||
assert.strictEqual(stdout, 'function bar(n){return 3*n}function baz(n){return n/2}\n');
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("bin/uglifyjs with multiple input file globs.", function(done) {
|
||||
var command = uglifyjscmd + ' "test/input/issue-1242/???.es5" "test/input/issue-1242/*.js" -mc toplevel,passes=3';
|
||||
|
||||
var command = [
|
||||
uglifyjscmd,
|
||||
'"test/input/issue-1242/???.es5"',
|
||||
'"test/input/issue-1242/*.js"',
|
||||
"--compress", "toplevel,passes=3",
|
||||
"--mangle",
|
||||
"--no-module",
|
||||
].join(" ");
|
||||
exec(command, function(err, stdout) {
|
||||
if (err) throw err;
|
||||
|
||||
assert.strictEqual(stdout, 'var print=console.log.bind(console);print("qux",9,6),print("Foo:",22);\n');
|
||||
done();
|
||||
});
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
var acorn = require("acorn");
|
||||
var assert = require("assert");
|
||||
var UglifyJS = require("../node");
|
||||
|
||||
@@ -8,15 +9,25 @@ describe("import", function() {
|
||||
"import A;",
|
||||
"import {};",
|
||||
"import `path`;",
|
||||
"{ import 'path'; }",
|
||||
"import from 'path';",
|
||||
"if (0) import 'path';",
|
||||
"import * from 'path';",
|
||||
"import 'A' from 'path';",
|
||||
"import A-B from 'path';",
|
||||
"import A as B from 'path';",
|
||||
"import { A }, B from 'path';",
|
||||
"import * as 'A' from 'path';",
|
||||
"import * as A-B from 'path';",
|
||||
"import * as A, B from 'path';",
|
||||
"import * as A, {} from 'path';",
|
||||
"import { * as A } from 'path';",
|
||||
"import { * as 'A' } from 'path';",
|
||||
"import { * as A-B } from 'path';",
|
||||
"function f() { import 'path'; }",
|
||||
"import { 42 as A } from 'path';",
|
||||
"import { A-B as C } from 'path';",
|
||||
"import { 'A' as 'B' } from 'path';",
|
||||
].forEach(function(code) {
|
||||
assert.throws(function() {
|
||||
UglifyJS.parse(code);
|
||||
@@ -25,4 +36,74 @@ describe("import", function() {
|
||||
}, code);
|
||||
});
|
||||
});
|
||||
it("Should compare `import` statements correctly", function() {
|
||||
[
|
||||
"import 'foo';",
|
||||
"import 'path';",
|
||||
"import A from 'path';",
|
||||
"import { A } from 'path';",
|
||||
"import * as A from 'path';",
|
||||
"import A, { B } from 'path';",
|
||||
"import A, * as B from 'path';",
|
||||
"import { A as B } from 'path';",
|
||||
"import A, { B, C as D } from 'path';",
|
||||
].forEach(function(c, i, stats) {
|
||||
var s = UglifyJS.parse(c);
|
||||
assert.ok(s instanceof UglifyJS.AST_Toplevel, c);
|
||||
assert.strictEqual(s.body.length, 1, c);
|
||||
assert.ok(s.body[0] instanceof UglifyJS.AST_Import, c);
|
||||
stats.forEach(function(d, j) {
|
||||
var t = UglifyJS.parse(d);
|
||||
assert.ok(t instanceof UglifyJS.AST_Toplevel, d);
|
||||
assert.strictEqual(t.body.length, 1, d);
|
||||
assert.ok(t.body[0] instanceof UglifyJS.AST_Import, d);
|
||||
assert.strictEqual(s.equals(t), i === j, c + "\n" + d);
|
||||
});
|
||||
});
|
||||
});
|
||||
it("Should interoperate with ESTree correctly", function() {
|
||||
[
|
||||
"import A from 'path';",
|
||||
"import * as A from 'path';",
|
||||
"import A, * as B from 'path';",
|
||||
"import { '42' as A, B } from 'path';",
|
||||
"import A, { '42' as B } from 'path';",
|
||||
].forEach(function(code) {
|
||||
var ast = UglifyJS.parse(code);
|
||||
try {
|
||||
var spidermonkey = ast.to_mozilla_ast();
|
||||
} catch (ex) {
|
||||
assert.fail("[to_mozilla_ast] " + ex.stack);
|
||||
}
|
||||
try {
|
||||
var ast2 = UglifyJS.AST_Node.from_mozilla_ast(spidermonkey);
|
||||
} catch (ex) {
|
||||
assert.fail("[from_mozilla_ast] " + ex.stack);
|
||||
}
|
||||
assert.strictEqual(ast2.print_to_string(), ast.print_to_string(), [
|
||||
"spidermonkey:",
|
||||
ast.print_to_string(),
|
||||
ast2.print_to_string(),
|
||||
].join("\n"));
|
||||
try {
|
||||
var acorn_est = acorn.parse(code, {
|
||||
ecmaVersion: "latest",
|
||||
locations: true,
|
||||
sourceType: "module",
|
||||
});
|
||||
} catch (ex) {
|
||||
assert.fail("[acorn.parse] " + ex.stack);
|
||||
}
|
||||
try {
|
||||
var ast3 = UglifyJS.AST_Node.from_mozilla_ast(acorn_est);
|
||||
} catch (ex) {
|
||||
assert.fail("[from_acorn] " + ex.stack);
|
||||
}
|
||||
assert.strictEqual(ast3.print_to_string(), ast.print_to_string(), [
|
||||
"acorn:",
|
||||
ast.print_to_string(),
|
||||
ast3.print_to_string(),
|
||||
].join("\n"));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -12,17 +12,16 @@ describe("let", function() {
|
||||
s += '}';
|
||||
var result = UglifyJS.minify(s, {
|
||||
compress: false,
|
||||
}).code;
|
||||
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
// Verify that select keywords and reserved keywords not produced
|
||||
[
|
||||
"do",
|
||||
"let",
|
||||
"var",
|
||||
].forEach(function(name) {
|
||||
assert.strictEqual(result.indexOf("var " + name + "="), -1);
|
||||
assert.strictEqual(result.code.indexOf("var " + name + "="), -1);
|
||||
});
|
||||
|
||||
// Verify that the variable names that appeared immediately before
|
||||
// and after the erroneously generated variable name still exist
|
||||
// to show the test generated enough symbols.
|
||||
@@ -31,27 +30,29 @@ describe("let", function() {
|
||||
"eet", "fet",
|
||||
"rar", "oar",
|
||||
].forEach(function(name) {
|
||||
assert.notStrictEqual(result.indexOf("var " + name + "="), -1);
|
||||
assert.notStrictEqual(result.code.indexOf("var " + name + "="), -1);
|
||||
});
|
||||
});
|
||||
it("Should quote mangled properties that are reserved keywords", function() {
|
||||
var s = '"rrrrrnnnnniiiiiaaaaa";';
|
||||
for (var i = 0; i < 18000; i++) {
|
||||
s += "v.b" + i + ";";
|
||||
s += "v.b" + i + "=v;";
|
||||
}
|
||||
var result = UglifyJS.minify(s, {
|
||||
compress: false,
|
||||
ie: true,
|
||||
mangle: {
|
||||
properties: true,
|
||||
}
|
||||
}).code;
|
||||
properties: {
|
||||
domprops: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
[
|
||||
"in",
|
||||
"var",
|
||||
].forEach(function(name) {
|
||||
assert.notStrictEqual(result.indexOf(name), -1);
|
||||
assert.notStrictEqual(result.indexOf('v["' + name + '"]'), -1);
|
||||
assert.notStrictEqual(result.code.indexOf('v["' + name + '"]'), -1);
|
||||
});
|
||||
});
|
||||
it("Should parse `let` as name correctly", function() {
|
||||
|
||||
@@ -6,8 +6,10 @@ describe("Input file as map", function() {
|
||||
var jsMap = {
|
||||
'/scripts/foo.js': 'var foo = {"x": 1, y: 2, \'z\': 3};'
|
||||
};
|
||||
var result = UglifyJS.minify(jsMap, {sourceMap: true});
|
||||
|
||||
var result = UglifyJS.minify(jsMap, {
|
||||
sourceMap: true,
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
var map = JSON.parse(result.map);
|
||||
assert.strictEqual(result.code, 'var foo={x:1,y:2,z:3};');
|
||||
assert.deepEqual(map.sources, ['/scripts/foo.js']);
|
||||
@@ -26,8 +28,10 @@ describe("Input file as map", function() {
|
||||
'var foo = {"x": 1, y: 2, \'z\': 3};',
|
||||
'var bar = 15;'
|
||||
];
|
||||
var result = UglifyJS.minify(jsSeq, {sourceMap: true});
|
||||
|
||||
var result = UglifyJS.minify(jsSeq, {
|
||||
sourceMap: true,
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
var map = JSON.parse(result.map);
|
||||
assert.strictEqual(result.code, 'var foo={x:1,y:2,z:3},bar=15;');
|
||||
assert.deepEqual(map.sources, ['0', '1']);
|
||||
@@ -37,8 +41,12 @@ describe("Input file as map", function() {
|
||||
var jsMap = {
|
||||
'/scripts/foo.js': 'var foo = {"x": 1, y: 2, \'z\': 3};'
|
||||
};
|
||||
var result = UglifyJS.minify(jsMap, {sourceMap: {includeSources: true}});
|
||||
|
||||
var result = UglifyJS.minify(jsMap, {
|
||||
sourceMap: {
|
||||
includeSources: true,
|
||||
},
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
var map = JSON.parse(result.map);
|
||||
assert.strictEqual(result.code, 'var foo={x:1,y:2,z:3};');
|
||||
assert.deepEqual(map.sourcesContent, ['var foo = {"x": 1, y: 2, \'z\': 3};']);
|
||||
|
||||
@@ -48,8 +48,8 @@ describe("minify", function() {
|
||||
var result = UglifyJS.minify(code, {
|
||||
mangle: {
|
||||
cache: cache,
|
||||
toplevel: true
|
||||
}
|
||||
toplevel: true,
|
||||
},
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
original += code;
|
||||
@@ -79,9 +79,9 @@ describe("minify", function() {
|
||||
var code = read("test/input/issue-1242/" + file);
|
||||
var result = UglifyJS.minify(code, {
|
||||
mangle: {
|
||||
toplevel: true
|
||||
toplevel: true,
|
||||
},
|
||||
nameCache: cache
|
||||
nameCache: cache,
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
original += code;
|
||||
@@ -110,10 +110,12 @@ describe("minify", function() {
|
||||
var result = UglifyJS.minify(code, {
|
||||
compress: false,
|
||||
mangle: {
|
||||
properties: true,
|
||||
toplevel: true
|
||||
properties: {
|
||||
domprops: true,
|
||||
},
|
||||
toplevel: true,
|
||||
},
|
||||
nameCache: cache
|
||||
nameCache: cache,
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
original += code;
|
||||
@@ -160,8 +162,9 @@ describe("minify", function() {
|
||||
var js = 'var foo = {"x": 1, y: 2, \'z\': 3};';
|
||||
var result = UglifyJS.minify(js, {
|
||||
output: {
|
||||
keep_quoted_props: true
|
||||
}});
|
||||
keep_quoted_props: true,
|
||||
},
|
||||
});
|
||||
assert.strictEqual(result.code, 'var foo={"x":1,y:2,"z":3};');
|
||||
});
|
||||
it("Should preserve quote styles when quote_style is 3", function() {
|
||||
@@ -169,8 +172,9 @@ describe("minify", function() {
|
||||
var result = UglifyJS.minify(js, {
|
||||
output: {
|
||||
keep_quoted_props: true,
|
||||
quote_style: 3
|
||||
}});
|
||||
quote_style: 3,
|
||||
},
|
||||
});
|
||||
assert.strictEqual(result.code, 'var foo={"x":1,y:2,\'z\':3};');
|
||||
});
|
||||
it("Should not preserve quotes in object literals when disabled", function() {
|
||||
@@ -178,8 +182,9 @@ describe("minify", function() {
|
||||
var result = UglifyJS.minify(js, {
|
||||
output: {
|
||||
keep_quoted_props: false,
|
||||
quote_style: 3
|
||||
}});
|
||||
quote_style: 3,
|
||||
},
|
||||
});
|
||||
assert.strictEqual(result.code, 'var foo={x:1,y:2,z:3};');
|
||||
});
|
||||
});
|
||||
@@ -188,32 +193,30 @@ describe("minify", function() {
|
||||
it("Shouldn't mangle quoted properties", function() {
|
||||
var js = 'a["foo"] = "bar"; a.color = "red"; x = {"bar": 10};';
|
||||
var result = UglifyJS.minify(js, {
|
||||
compress: {
|
||||
properties: false
|
||||
},
|
||||
compress: true,
|
||||
mangle: {
|
||||
properties: {
|
||||
keep_quoted: true
|
||||
}
|
||||
domprops: true,
|
||||
keep_quoted: true,
|
||||
},
|
||||
},
|
||||
output: {
|
||||
keep_quoted_props: true,
|
||||
quote_style: 3
|
||||
}
|
||||
quote_style: 3,
|
||||
},
|
||||
});
|
||||
assert.strictEqual(result.code,
|
||||
'a["foo"]="bar",a.a="red",x={"bar":10};');
|
||||
assert.strictEqual(result.code, 'a["foo"]="bar",a.a="red",x={"bar":10};');
|
||||
});
|
||||
it("Should not mangle quoted property within dead code", function() {
|
||||
var result = UglifyJS.minify('({ "keep": 1 }); g.keep = g.change;', {
|
||||
var result = UglifyJS.minify('({ "keep": 1 }); g.keep = g.change = 42;', {
|
||||
mangle: {
|
||||
properties: {
|
||||
keep_quoted: true
|
||||
}
|
||||
}
|
||||
keep_quoted: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
assert.strictEqual(result.code, "g.keep=g.g;");
|
||||
assert.strictEqual(result.code, "g.keep=g.g=42;");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -223,7 +226,7 @@ describe("minify", function() {
|
||||
output: {
|
||||
comments: "all",
|
||||
beautify: false,
|
||||
}
|
||||
},
|
||||
});
|
||||
var code = result.code;
|
||||
assert.strictEqual(code, "// comment1 comment2\nbar();");
|
||||
@@ -233,7 +236,7 @@ describe("minify", function() {
|
||||
output: {
|
||||
comments: "all",
|
||||
beautify: false,
|
||||
}
|
||||
},
|
||||
});
|
||||
var code = result.code;
|
||||
assert.strictEqual(code, "var a=function(){foo()}();");
|
||||
@@ -301,7 +304,7 @@ describe("minify", function() {
|
||||
compress: false,
|
||||
mangle: false,
|
||||
output: {
|
||||
ast: true
|
||||
ast: true,
|
||||
},
|
||||
}).ast;
|
||||
assert.strictEqual(ast.TYPE, "Toplevel");
|
||||
@@ -312,9 +315,9 @@ describe("minify", function() {
|
||||
var stat = ast.body[0].body[0];
|
||||
UglifyJS.minify(ast, {
|
||||
compress: {
|
||||
sequences: false
|
||||
sequences: false,
|
||||
},
|
||||
mangle: false
|
||||
mangle: false,
|
||||
});
|
||||
assert.ok(stat.body);
|
||||
assert.strictEqual(stat.print_to_string(), "a=x()");
|
||||
|
||||
@@ -50,12 +50,10 @@ describe("Number literals", function() {
|
||||
"0.000_000_004_2e+1_0-0B101_010+0x2_A-0o5_2+4_2",
|
||||
].forEach(function(code) {
|
||||
var result = UglifyJS.minify(code, {
|
||||
compress: {
|
||||
expression: true,
|
||||
},
|
||||
expression: true,
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
assert.strictEqual(result.code, "42;");
|
||||
assert.strictEqual(result.code, "42");
|
||||
});
|
||||
});
|
||||
it("Should reject invalid use of underscore", function() {
|
||||
|
||||
@@ -236,9 +236,9 @@ describe("test/reduce.js", function() {
|
||||
});
|
||||
it("Should report trailing whitespace difference in stringified format", function() {
|
||||
var code = [
|
||||
"for (var a in (1 - .8).toString()) {",
|
||||
"[].forEach.call((1 - .8).toString(), function() {",
|
||||
" console.log();",
|
||||
"}",
|
||||
"});",
|
||||
].join("\n");
|
||||
var result = reduce_test(code, {
|
||||
compress: {
|
||||
@@ -333,6 +333,7 @@ describe("test/reduce.js", function() {
|
||||
unsafe_math: true,
|
||||
},
|
||||
mangle: false,
|
||||
module: false,
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
assert.strictEqual(result.code, [
|
||||
@@ -346,7 +347,8 @@ describe("test/reduce.js", function() {
|
||||
'// "compress": {',
|
||||
'// "unsafe_math": true',
|
||||
'// },',
|
||||
'// "mangle": false',
|
||||
'// "mangle": false,',
|
||||
'// "module": false',
|
||||
"// }",
|
||||
].join("\n"));
|
||||
});
|
||||
@@ -449,6 +451,27 @@ describe("test/reduce.js", function() {
|
||||
].join("\n"));
|
||||
});
|
||||
it("Should transform `export default function` correctly", function() {
|
||||
if (semver.satisfies(process.version, "<8")) return;
|
||||
var code = [
|
||||
"export default function f(a) {",
|
||||
" for (var k in a)",
|
||||
" console.log(k);",
|
||||
" (async function() {})();",
|
||||
"}",
|
||||
"f(this);",
|
||||
].join("\n");
|
||||
var result = reduce_test(code, {
|
||||
mangle: false,
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
assert.strictEqual(result.code, [
|
||||
"// Can't reproduce test failure",
|
||||
"// minify options: {",
|
||||
'// "mangle": false',
|
||||
"// }",
|
||||
].join("\n"));
|
||||
});
|
||||
it("Should transform `export default (function)` correctly", function() {
|
||||
var code = [
|
||||
"for (var k in this)",
|
||||
" console.log(k);",
|
||||
|
||||
@@ -19,11 +19,11 @@ function source_map(code) {
|
||||
function get_map() {
|
||||
return {
|
||||
"version": 3,
|
||||
"sources": ["index.js"],
|
||||
"sources": [ "index.js" ],
|
||||
"names": [],
|
||||
"mappings": ";;AAAA,IAAI,MAAM,SAAN,GAAM;AAAA,SAAK,SAAS,CAAd;AAAA,CAAV;AACA,QAAQ,GAAR,CAAY,IAAI,KAAJ,CAAZ",
|
||||
"file": "bundle.js",
|
||||
"sourcesContent": ["let foo = x => \"foo \" + x;\nconsole.log(foo(\"bar\"));"]
|
||||
"sourcesContent": [ "let foo = x => \"foo \" + x;\nconsole.log(foo(\"bar\"));" ],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ function prepare_map(sourceMap) {
|
||||
sourceMap: {
|
||||
content: sourceMap,
|
||||
includeSources: true,
|
||||
}
|
||||
},
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
return JSON.parse(result.map);
|
||||
@@ -112,7 +112,7 @@ describe("sourcemaps", function() {
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
assert.strictEqual(result.code, "class A{static P=42;set#q(s){}}");
|
||||
assert.strictEqual(result.map, '{"version":3,"sources":["0"],"names":["A","P","#q","v"],"mappings":"MAAMA,EACFC,SAAW,GACXC,MAAOC"}');
|
||||
assert.strictEqual(result.map, '{"version":3,"sources":["0"],"names":["A","P","#q","v"],"mappings":"MAAMA,EACFC,SAAW,GACXC,MAAOC,IACX"}');
|
||||
});
|
||||
it("Should mark array/object literals", function() {
|
||||
var result = UglifyJS.minify([
|
||||
@@ -124,7 +124,7 @@ describe("sourcemaps", function() {
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
assert.strictEqual(result.code, "({}).wat([]);");
|
||||
assert.strictEqual(result.map, '{"version":3,"sources":["0"],"names":["wat"],"mappings":"CAAU,IACNA,IAAI"}');
|
||||
assert.strictEqual(result.map, '{"version":3,"sources":["0"],"names":["wat"],"mappings":"CAAU,IACNA,IAAI,EAAE"}');
|
||||
});
|
||||
it("Should give correct sourceRoot", function() {
|
||||
var code = "console.log(42);";
|
||||
@@ -135,7 +135,7 @@ describe("sourcemaps", function() {
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
assert.strictEqual(result.code, code);
|
||||
assert.strictEqual(result.map, '{"version":3,"sourceRoot":"//foo.bar/","sources":["0"],"names":["console","log"],"mappings":"AAAAA,QAAQC,IAAI"}');
|
||||
assert.strictEqual(result.map, '{"version":3,"sourceRoot":"//foo.bar/","sources":["0"],"names":["console","log"],"mappings":"AAAAA,QAAQC,IAAI,EAAE"}');
|
||||
});
|
||||
it("Should produce same source map with DOS or UNIX line endings", function() {
|
||||
var code = [
|
||||
@@ -160,8 +160,8 @@ describe("sourcemaps", function() {
|
||||
sourceMap: {
|
||||
content: read("test/input/issue-1236/simple.js.map"),
|
||||
filename: "simple.min.js",
|
||||
includeSources: true
|
||||
}
|
||||
includeSources: true,
|
||||
},
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
var map = JSON.parse(result.map);
|
||||
@@ -175,8 +175,8 @@ describe("sourcemaps", function() {
|
||||
sourceMap: {
|
||||
content: "inline",
|
||||
includeSources: true,
|
||||
url: "inline"
|
||||
}
|
||||
url: "inline",
|
||||
},
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
assert.strictEqual(result.code + "\n", read("test/input/issue-520/output.js"));
|
||||
@@ -185,7 +185,7 @@ describe("sourcemaps", function() {
|
||||
var result = UglifyJS.minify(read("test/input/issue-1323/sample.js"), {
|
||||
mangle: false,
|
||||
sourceMap: {
|
||||
content: "inline"
|
||||
content: "inline",
|
||||
},
|
||||
warnings: true,
|
||||
});
|
||||
@@ -206,7 +206,7 @@ describe("sourcemaps", function() {
|
||||
if (result.error) throw result.error;
|
||||
assert.strictEqual(result.code, [
|
||||
"var Foo=function(){console.log(3)},bar=(new Foo,function(o){return o});",
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIiwiMSJdLCJuYW1lcyI6WyJGb28iLCJjb25zb2xlIiwibG9nIiwiYmFyIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFNQSxJQUFJLFdBQWdCQyxRQUFRQyxJQUFJLElDQWxDQyxLREEyQyxJQUFJSCxJQ0MvQyxTQUFjRyxHQUNWLE9BQU9BIn0=",
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIiwiMSJdLCJuYW1lcyI6WyJGb28iLCJjb25zb2xlIiwibG9nIiwiYmFyIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFNQSxJQUFJLFdBQWdCQyxRQUFRQyxJQUFJLENBQUcsQ0FBRSxFQ0F2Q0MsS0RBMkMsSUFBSUgsSUNDL0MsU0FBY0csR0FDVixPQUFPQSxDQUNYIn0=",
|
||||
].join("\n"));
|
||||
assert.deepEqual(result.warnings, [ "WARN: inline source map not found: 1" ]);
|
||||
});
|
||||
@@ -239,13 +239,13 @@ describe("sourcemaps", function() {
|
||||
sourceMap: {
|
||||
content: "inline",
|
||||
includeSources: true,
|
||||
url: "inline"
|
||||
}
|
||||
url: "inline",
|
||||
},
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
assert.strictEqual(result.code + "\n", read("test/input/issue-3294/output.js"));
|
||||
});
|
||||
it("Should work in presence of unrecognised annotations", function() {
|
||||
it("Should work in presence of unrecognized annotations", function() {
|
||||
var result = UglifyJS.minify(read("test/input/issue-3441/input.js"), {
|
||||
compress: false,
|
||||
mangle: false,
|
||||
@@ -255,7 +255,7 @@ describe("sourcemaps", function() {
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
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,OAAZ"}');
|
||||
});
|
||||
it("Should not overwrite existing sourcesContent", function() {
|
||||
var result = UglifyJS.minify({
|
||||
@@ -296,16 +296,16 @@ describe("sourcemaps", function() {
|
||||
it("Should append source map to output js when sourceMapInline is enabled", function() {
|
||||
var result = UglifyJS.minify('var a = function(foo) { return foo; };', {
|
||||
sourceMap: {
|
||||
url: "inline"
|
||||
}
|
||||
url: "inline",
|
||||
},
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
var code = result.code;
|
||||
assert.strictEqual(code, "var a=function(n){return n};\n" +
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjAiXSwibmFtZXMiOlsiYSIsImZvbyJdLCJtYXBwaW5ncyI6IkFBQUEsSUFBSUEsRUFBSSxTQUFTQyxHQUFPLE9BQU9BIn0=");
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjAiXSwibmFtZXMiOlsiYSIsImZvbyJdLCJtYXBwaW5ncyI6IkFBQUEsSUFBSUEsRUFBSSxTQUFTQyxHQUFPLE9BQU9BLENBQUsifQ==");
|
||||
});
|
||||
it("Should not append source map to output js when sourceMapInline is not enabled", function() {
|
||||
var result = UglifyJS.minify('var a = function(foo) { return foo; };');
|
||||
var result = UglifyJS.minify("var a = function(foo) { return foo; };");
|
||||
if (result.error) throw result.error;
|
||||
var code = result.code;
|
||||
assert.strictEqual(code, "var a=function(n){return n};");
|
||||
@@ -316,11 +316,11 @@ describe("sourcemaps", function() {
|
||||
directives: false,
|
||||
},
|
||||
output: {
|
||||
max_line_len: 20
|
||||
max_line_len: 20,
|
||||
},
|
||||
sourceMap: {
|
||||
url: "inline"
|
||||
}
|
||||
url: "inline",
|
||||
},
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
assert.strictEqual(result.code, read("test/input/issue-505/output.js"));
|
||||
@@ -334,7 +334,7 @@ describe("sourcemaps", function() {
|
||||
sourceMap: {
|
||||
includeSources: true,
|
||||
url: "inline",
|
||||
}
|
||||
},
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
var map = JSON.parse(result.map);
|
||||
@@ -348,7 +348,7 @@ describe("sourcemaps", function() {
|
||||
sourceMap: {
|
||||
content: "inline",
|
||||
includeSources: true,
|
||||
}
|
||||
},
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
map = JSON.parse(result.map);
|
||||
|
||||
@@ -9,19 +9,22 @@ function beautify(ast) {
|
||||
var beautified = UglifyJS.minify(ast, {
|
||||
compress: false,
|
||||
mangle: false,
|
||||
module: ufuzz.module,
|
||||
output: {
|
||||
ast: true,
|
||||
beautify: true,
|
||||
braces: true,
|
||||
},
|
||||
});
|
||||
if (beautified.error) return beautified;
|
||||
return UglifyJS.minify(beautified.code, {
|
||||
compress: false,
|
||||
mangle: false,
|
||||
output: {
|
||||
ast: true,
|
||||
},
|
||||
});
|
||||
if (!beautified.error) {
|
||||
var verify = UglifyJS.minify(beautified.code, {
|
||||
compress: false,
|
||||
mangle: false,
|
||||
module: ufuzz.module,
|
||||
});
|
||||
if (verify.error) return verify;
|
||||
}
|
||||
return beautified;
|
||||
}
|
||||
|
||||
function validate(ast) {
|
||||
@@ -35,6 +38,7 @@ function validate(ast) {
|
||||
return UglifyJS.minify(ast, {
|
||||
compress: false,
|
||||
mangle: false,
|
||||
module: ufuzz.module,
|
||||
output: {
|
||||
ast: true,
|
||||
},
|
||||
@@ -57,12 +61,12 @@ function test(input, to_moz, description, skip_on_error, beautified) {
|
||||
var ast = UglifyJS.AST_Node.from_mozilla_ast(to_moz(input));
|
||||
} catch (e) {
|
||||
if (skip_on_error) return true;
|
||||
console.log("//=============================================================");
|
||||
console.log("//", description, "failed... round", round);
|
||||
console.log(e);
|
||||
console.log("// original code");
|
||||
if (beautified === true) console.log("// (beautified)");
|
||||
console.log(input.code);
|
||||
console.error("//=============================================================");
|
||||
console.error("//", description, "failed... round", round);
|
||||
console.error(e);
|
||||
console.error("// original code");
|
||||
if (beautified === true) console.error("// (beautified)");
|
||||
console.error(input.code);
|
||||
return false;
|
||||
}
|
||||
var transformed = validate(ast);
|
||||
@@ -74,34 +78,34 @@ function test(input, to_moz, description, skip_on_error, beautified) {
|
||||
if (!test(beautified, to_moz, description, skip_on_error, true)) return false;
|
||||
}
|
||||
}
|
||||
console.log("//=============================================================");
|
||||
console.log("// !!!!!! Failed... round", round);
|
||||
console.log("// original code");
|
||||
console.error("//=============================================================");
|
||||
console.error("// !!!!!! Failed... round", round);
|
||||
console.error("// original code");
|
||||
if (beautified.error) {
|
||||
console.log("// !!! beautify failed !!!");
|
||||
console.log(beautified.error.stack);
|
||||
console.error("// !!! beautify failed !!!");
|
||||
console.error(beautified.error.stack);
|
||||
} else if (beautified === true) {
|
||||
console.log("// (beautified)");
|
||||
console.error("// (beautified)");
|
||||
}
|
||||
console.log(input.raw);
|
||||
console.log();
|
||||
console.log();
|
||||
console.log("//-------------------------------------------------------------");
|
||||
console.log("//", description);
|
||||
console.error(input.raw);
|
||||
console.error();
|
||||
console.error();
|
||||
console.error("//-------------------------------------------------------------");
|
||||
console.error("//", description);
|
||||
if (transformed.error) {
|
||||
console.log(transformed.error.stack);
|
||||
console.error(transformed.error.stack);
|
||||
} else {
|
||||
beautified = beautify(transformed.ast);
|
||||
if (beautified.error) {
|
||||
console.log("// !!! beautify failed !!!");
|
||||
console.log(beautified.error.stack);
|
||||
console.log(transformed.code);
|
||||
console.error("// !!! beautify failed !!!");
|
||||
console.error(beautified.error.stack);
|
||||
console.error(transformed.code);
|
||||
} else {
|
||||
console.log("// (beautified)");
|
||||
console.log(beautified.code);
|
||||
console.error("// (beautified)");
|
||||
console.error(beautified.code);
|
||||
}
|
||||
}
|
||||
console.log("!!!!!! Failed... round", round);
|
||||
console.error("!!!!!! Failed... round", round);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -115,9 +119,29 @@ for (var round = 1; round <= num_iterations; round++) {
|
||||
var code = ufuzz.createTopLevelCode();
|
||||
minify_options.forEach(function(options) {
|
||||
var ok = true;
|
||||
var input = UglifyJS.minify(options ? UglifyJS.minify(code, JSON.parse(options)).code : code, {
|
||||
var minified;
|
||||
if (options) {
|
||||
var o = JSON.parse(options);
|
||||
o.module = ufuzz.module;
|
||||
minified = UglifyJS.minify(code, o);
|
||||
if (minified.error) {
|
||||
console.log("//=============================================================");
|
||||
console.log("// minify() failed... round", round);
|
||||
console.log("// original code");
|
||||
console.log(code);
|
||||
console.log();
|
||||
console.log();
|
||||
console.log("//-------------------------------------------------------------");
|
||||
console.log("minify(options):");
|
||||
console.log(JSON.stringify(o, null, 2));
|
||||
return;
|
||||
}
|
||||
minified = minified.code;
|
||||
}
|
||||
var input = UglifyJS.minify(minified || code, {
|
||||
compress: false,
|
||||
mangle: false,
|
||||
module: ufuzz.module,
|
||||
output: {
|
||||
ast: true,
|
||||
},
|
||||
@@ -125,11 +149,27 @@ for (var round = 1; round <= num_iterations; round++) {
|
||||
input.raw = options ? input.code : code;
|
||||
if (input.error) {
|
||||
ok = false;
|
||||
console.log("//=============================================================");
|
||||
console.log("// minify() failed... round", round);
|
||||
console.log(input.error);
|
||||
console.log("// original code");
|
||||
console.log(code);
|
||||
console.error("//=============================================================");
|
||||
console.error("// parse() failed... round", round);
|
||||
console.error("// original code");
|
||||
console.error(code);
|
||||
console.error();
|
||||
console.error();
|
||||
if (options) {
|
||||
console.error("//-------------------------------------------------------------");
|
||||
console.error("// minified code");
|
||||
console.error(minified);
|
||||
console.error();
|
||||
console.error();
|
||||
console.error("//-------------------------------------------------------------");
|
||||
console.error("minify(options):");
|
||||
console.error(JSON.stringify(o, null, 2));
|
||||
console.error();
|
||||
console.error();
|
||||
}
|
||||
console.error("//-------------------------------------------------------------");
|
||||
console.error("// parse() error");
|
||||
console.error(input.error);
|
||||
}
|
||||
if (ok) ok = test(input, function(input) {
|
||||
return input.ast.to_mozilla_ast();
|
||||
@@ -141,7 +181,10 @@ for (var round = 1; round <= num_iterations; round++) {
|
||||
sourceType: "module",
|
||||
});
|
||||
}, "acorn.parse()", !ufuzz.verbose);
|
||||
if (!ok) process.exit(1);
|
||||
if (!ok && isFinite(num_iterations)) {
|
||||
console.log();
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
console.log();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
var fs = require("fs");
|
||||
|
||||
new Function("exports", require("../tools/node").FILES.map(function(file) {
|
||||
new Function("domprops", "exports", require("../tools/node").FILES.map(function(file) {
|
||||
if (/exports\.js$/.test(file)) file = require.resolve("./exports");
|
||||
return fs.readFileSync(file, "utf8");
|
||||
}).join("\n\n"))(exports);
|
||||
}).join("\n\n"))(require("../tools/domprops.json"), exports);
|
||||
|
||||
123
test/reduce.js
123
test/reduce.js
@@ -20,6 +20,9 @@ Error.stackTraceLimit = Infinity;
|
||||
module.exports = function reduce_test(testcase, minify_options, reduce_options) {
|
||||
minify_options = minify_options || {};
|
||||
reduce_options = reduce_options || {};
|
||||
var parse_options = {
|
||||
module: minify_options.module || minify_options.module === undefined,
|
||||
}
|
||||
var print_options = {};
|
||||
[
|
||||
"ie",
|
||||
@@ -160,6 +163,11 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
||||
return expr instanceof U.AST_Spread ? expr.expression : expr;
|
||||
}
|
||||
}
|
||||
else if (node instanceof U.AST_Await) {
|
||||
node.start._permute++;
|
||||
CHANGED = true;
|
||||
return node.expression;
|
||||
}
|
||||
else if (node instanceof U.AST_Binary) {
|
||||
var permute = ((node.start._permute += step) * steps | 0) % 4;
|
||||
var expr = [
|
||||
@@ -185,7 +193,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
||||
}
|
||||
else if (node instanceof U.AST_BlockStatement) {
|
||||
if (in_list && node.body.filter(function(node) {
|
||||
return node instanceof U.AST_Const;
|
||||
return node instanceof U.AST_Const || node instanceof U.AST_Let;
|
||||
}).length == 0) {
|
||||
node.start._permute++;
|
||||
CHANGED = true;
|
||||
@@ -241,23 +249,6 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
||||
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) {
|
||||
switch (((node.start._permute += step) * steps | 0) % 2) {
|
||||
case 0:
|
||||
@@ -275,6 +266,23 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
||||
}
|
||||
}
|
||||
}
|
||||
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_DWLoop) {
|
||||
var expr = [
|
||||
node.condition,
|
||||
@@ -296,6 +304,16 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
||||
return to_statement(expr);
|
||||
}
|
||||
}
|
||||
else if (node instanceof U.AST_ExportDeclaration) {
|
||||
node.start._permute++;
|
||||
CHANGED = true;
|
||||
return node.body;
|
||||
}
|
||||
else if (node instanceof U.AST_ExportDefault) {
|
||||
node.start._permute++;
|
||||
CHANGED = true;
|
||||
return to_statement(node.body);
|
||||
}
|
||||
else if (node instanceof U.AST_Finally) {
|
||||
// drop finally block
|
||||
node.start._permute++;
|
||||
@@ -317,19 +335,21 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
||||
}
|
||||
else if (node instanceof U.AST_ForEnumeration) {
|
||||
var expr;
|
||||
switch ((node.start._permute * steps | 0) % 3) {
|
||||
switch ((node.start._permute * steps | 0) % 4) {
|
||||
case 0:
|
||||
if (node.init instanceof U.AST_Definitions) {
|
||||
if (node.init instanceof U.AST_Const) break;
|
||||
if (node.init.definitions[0].name instanceof U.AST_Destructured) break;
|
||||
}
|
||||
expr = node.init;
|
||||
break;
|
||||
case 1:
|
||||
expr = node.object;
|
||||
break;
|
||||
case 1:
|
||||
expr = wrap_with_console_log(node.object);
|
||||
break;
|
||||
case 2:
|
||||
if (!has_loopcontrol(node.body, node, parent)) expr = node.body;
|
||||
if (has_loopcontrol(node.body, node, parent)) break;
|
||||
expr = node.body;
|
||||
break;
|
||||
case 3:
|
||||
if (!(node.init instanceof U.AST_Var)) break;
|
||||
if (node.init.definitions[0].name instanceof U.AST_Destructured) break;
|
||||
expr = node.init;
|
||||
break;
|
||||
}
|
||||
node.start._permute += step;
|
||||
@@ -343,14 +363,31 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
||||
node.condition,
|
||||
node.body,
|
||||
node.alternative,
|
||||
][ (node.start._permute * steps | 0) % 3 ];
|
||||
node,
|
||||
][ (node.start._permute * steps | 0) % 4 ];
|
||||
node.start._permute += step;
|
||||
if (expr) {
|
||||
if (expr === node) {
|
||||
if (node.alternative) {
|
||||
expr = node.clone();
|
||||
expr.alternative = null;
|
||||
CHANGED = true;
|
||||
return expr;
|
||||
}
|
||||
} else if (expr) {
|
||||
// replace if statement with its condition, then block or else block
|
||||
CHANGED = true;
|
||||
return to_statement(expr);
|
||||
}
|
||||
}
|
||||
else if (node instanceof U.AST_LabeledStatement) {
|
||||
if (node.body instanceof U.AST_Statement
|
||||
&& !has_loopcontrol(node.body, node.body, node)) {
|
||||
// replace labelled statement with its non-labelled body
|
||||
node.start._permute = REPLACEMENTS.length;
|
||||
CHANGED = true;
|
||||
return node.body;
|
||||
}
|
||||
}
|
||||
else if (node instanceof U.AST_Object) {
|
||||
// first property's value
|
||||
var expr = node.properties[0];
|
||||
@@ -441,13 +478,14 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
||||
return to_statement(node.definitions[0].value);
|
||||
}
|
||||
}
|
||||
else if (node instanceof U.AST_LabeledStatement) {
|
||||
if (node.body instanceof U.AST_Statement
|
||||
&& !has_loopcontrol(node.body, node.body, node)) {
|
||||
// replace labelled statement with its non-labelled body
|
||||
node.start._permute = REPLACEMENTS.length;
|
||||
else if (node instanceof U.AST_VarDef) {
|
||||
if (node.value && !(node.name instanceof U.AST_Destructured || parent instanceof U.AST_Const)) {
|
||||
node.start._permute++;
|
||||
CHANGED = true;
|
||||
return node.body;
|
||||
return new U.AST_VarDef({
|
||||
name: node.name,
|
||||
start: {},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -514,7 +552,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
||||
var before_iterations, diff_error_message, passes = 3, testcase_ast;
|
||||
for (var pass = 1; pass <= passes; pass++) {
|
||||
if (before_iterations !== testcase) {
|
||||
testcase_ast = U.parse(testcase);
|
||||
testcase_ast = U.parse(testcase, parse_options);
|
||||
if (diff_error_message === testcase) {
|
||||
// only difference detected is in error message, so expose that and try again
|
||||
testcase_ast.transform(new U.TreeTransformer(function(node, descend) {
|
||||
@@ -536,7 +574,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
||||
testcase = code;
|
||||
differs = diff;
|
||||
} else {
|
||||
testcase_ast = U.parse(testcase);
|
||||
testcase_ast = U.parse(testcase, parse_options);
|
||||
}
|
||||
}
|
||||
diff_error_message = null;
|
||||
@@ -596,6 +634,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
||||
var beautified = U.minify(testcase, {
|
||||
compress: false,
|
||||
mangle: false,
|
||||
module: minify_options.module,
|
||||
output: function() {
|
||||
var options = JSON.parse(JSON.stringify(print_options));
|
||||
options.beautify = true;
|
||||
@@ -748,7 +787,7 @@ function run_code(code, toplevel, result_cache, timeout) {
|
||||
if (!value) {
|
||||
var start = Date.now();
|
||||
result_cache[key] = value = {
|
||||
result: sandbox.run_code(sandbox.patch_module_statements(code), toplevel, timeout),
|
||||
result: sandbox.run_code(code, toplevel, timeout),
|
||||
elapsed: Date.now() - start,
|
||||
};
|
||||
}
|
||||
@@ -776,13 +815,7 @@ function compare_run_code(code, minify_options, result_cache, max_timeout) {
|
||||
};
|
||||
|
||||
function run(code, timeout) {
|
||||
if (minify_options.module) code = [
|
||||
'"use strict";',
|
||||
"(async function(){",
|
||||
code,
|
||||
"})();"
|
||||
].join("\n");
|
||||
return run_code(code, toplevel, result_cache, timeout);
|
||||
return run_code(sandbox.patch_module_statements(code, minify_options.module), toplevel, result_cache, timeout);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
require("./run")([
|
||||
"-b",
|
||||
"-b braces",
|
||||
"-m",
|
||||
"-mc passes=3",
|
||||
"-mc passes=3,toplevel",
|
||||
"-mb braces",
|
||||
"--toplevel -c",
|
||||
"--no-module -mc",
|
||||
"-mc passes=3,unsafe",
|
||||
"-mc keep_fargs=false,passes=3",
|
||||
"-mc keep_fargs=false,passes=3,pure_getters,unsafe,unsafe_comps,unsafe_math,unsafe_proto",
|
||||
].map(function(options) {
|
||||
var args = options.split(/ /);
|
||||
|
||||
@@ -41,6 +41,11 @@ rm -rf tmp/buble \
|
||||
@@ -309 +309 @@ export default class BlockStatement extends Node {
|
||||
- let cont = false; // TODO implement proper continue...
|
||||
+ let cont = !declarations; // TODO implement proper continue...
|
||||
--- a/src/program/types/VariableDeclaration.js
|
||||
+++ b/src/program/types/VariableDeclaration.js
|
||||
@@ -38 +38 @@ export default class VariableDeclaration extends Node {
|
||||
- code.remove(c, declarator.id.start);
|
||||
+ code.remove(c, declarator.id.start, lastDeclaratorIsPattern);
|
||||
EOF
|
||||
ERR=$?; if [ "$ERR" != "0" ]; then echo "Error: $ERR"; exit $ERR; fi
|
||||
minify_in_situ "src" \
|
||||
|
||||
@@ -36,7 +36,7 @@ EOF
|
||||
}
|
||||
if [ $NATIVE ]; then unset -f timeout; fi
|
||||
|
||||
while !(git clone --branch v1.6.0 --depth 1 https://github.com/jasongin/nvs.git ~/.nvs); do
|
||||
while !(git clone --branch v1.6.2 --depth 1 https://github.com/jasongin/nvs.git ~/.nvs); do
|
||||
rm -rf ~/.nvs
|
||||
done
|
||||
while ! timeout 60 bash -c ". ~/.nvs/nvs.sh add $NODE && nvs use $NODE"; do
|
||||
@@ -48,7 +48,10 @@ done
|
||||
nvs use $NODE
|
||||
node --version
|
||||
npm config set audit false
|
||||
npm config set optional false
|
||||
npm config set fund false
|
||||
npm config set loglevel error
|
||||
npm config set omit optional || true
|
||||
npm config set optional false || true
|
||||
npm config set save false
|
||||
npm config set strict-ssl false
|
||||
npm config set update-notifier false
|
||||
|
||||
@@ -4,6 +4,7 @@ require("./run")([
|
||||
].map(function(options) {
|
||||
var args = options.split(/ /);
|
||||
args.unshift("test/jetstream.js");
|
||||
args.push("-b", "beautify=false,webkit");
|
||||
args.push("-O", "webkit");
|
||||
args.push("--no-module");
|
||||
return args;
|
||||
}));
|
||||
|
||||
@@ -35,18 +35,27 @@ npm_install() {
|
||||
done
|
||||
}
|
||||
|
||||
workaround() {
|
||||
FILE="$1"
|
||||
echo 'Monkey patching' $FILE
|
||||
CODE=`cat $FILE`
|
||||
sed -E 's/for ?\((var [^;{]+;)/\1for\(;/g' > $FILE <<EOF
|
||||
$CODE
|
||||
EOF
|
||||
}
|
||||
|
||||
rm -rf tmp/sucrase \
|
||||
&& git clone https://github.com/alangpierce/sucrase.git tmp/sucrase \
|
||||
&& cd tmp/sucrase \
|
||||
&& rm -rf .git/hooks \
|
||||
&& git checkout 38b66f3009feb76750a799deea211adcc83574f1 \
|
||||
&& git checkout 7284b3733aa114b3f4f5371e36ff5a4704ec860e \
|
||||
&& patch -l -p1 <<EOF
|
||||
--- a/package.json
|
||||
+++ b/package.json
|
||||
@@ -25 +24,0 @@
|
||||
- "prepublishOnly": "yarn clean && yarn build",
|
||||
@@ -65 +63,0 @@
|
||||
- "test262-harness": "^6.5.0",
|
||||
@@ -69 +67,0 @@
|
||||
- "test262-harness": "^10.0.0",
|
||||
--- a/script/build.ts
|
||||
+++ b/script/build.ts
|
||||
@@ -16 +15,0 @@ async function main(): Promise<void> {
|
||||
@@ -57,11 +66,11 @@ rm -rf tmp/sucrase \
|
||||
- () => buildIntegration("./integrations/webpack-loader"),
|
||||
- () => buildIntegration("./integrations/webpack-object-rest-spread-plugin"),
|
||||
- () => buildWebsite(),
|
||||
@@ -66,3 +59,0 @@ async function buildSucrase(): Promise<void> {
|
||||
@@ -62,3 +55,0 @@ async function buildSucrase(): Promise<void> {
|
||||
- // Also add in .d.ts files from tsc, which only need to be compiled once.
|
||||
- await run(\`\${TSC} --project ./src --outDir ./dist-types\`);
|
||||
- await mergeDirectoryContents("./dist-types/src", "./dist");
|
||||
@@ -70 +61 @@ async function buildSucrase(): Promise<void> {
|
||||
- await mergeDirectoryContents("./dist-types/src", "./dist/types");
|
||||
@@ -66 +57 @@ async function buildSucrase(): Promise<void> {
|
||||
- await run("yarn link");
|
||||
+ await run("npm link");
|
||||
--- a/src/identifyShadowedGlobals.ts
|
||||
@@ -70,28 +79,38 @@ rm -rf tmp/sucrase \
|
||||
+export { identifyShadowedGlobals as HACK };
|
||||
--- a/src/parser/tokenizer/state.ts
|
||||
+++ b/src/parser/tokenizer/state.ts
|
||||
@@ -100,0 +101 @@ export default class State {
|
||||
@@ -106,0 +107 @@ export default class State {
|
||||
+export { State as HACK };
|
||||
--- a/src/transformers/JSXTransformer.ts
|
||||
+++ b/src/transformers/JSXTransformer.ts
|
||||
@@ -253,0 +254 @@ export default class JSXTransformer extends Transformer {
|
||||
@@ -560,0 +561 @@ export default class JSXTransformer extends Transformer {
|
||||
+export { JSXTransformer as HACK };
|
||||
--- a/src/util/getClassInfo.ts
|
||||
+++ b/src/util/getClassInfo.ts
|
||||
@@ -164,0 +165 @@ export default function getClassInfo(
|
||||
@@ -195,0 +196 @@ export default function getClassInfo(
|
||||
+export { getClassInfo as HACK };
|
||||
--- a/src/util/getDeclarationInfo.ts
|
||||
+++ b/src/util/getDeclarationInfo.ts
|
||||
@@ -40,0 +41 @@ export default function getDeclarationInfo(tokens: TokenProcessor): DeclarationI
|
||||
+export { getDeclarationInfo as HACK };
|
||||
--- a/src/util/getImportExportSpecifierInfo.ts
|
||||
+++ b/src/util/getImportExportSpecifierInfo.ts
|
||||
@@ -87,0 +88 @@ export default function getImportExportSpecifierInfo(
|
||||
+export { getImportExportSpecifierInfo as HACK };
|
||||
--- a/src/util/getJSXPragmaInfo.ts
|
||||
+++ b/src/util/getJSXPragmaInfo.ts
|
||||
@@ -14,0 +15 @@ export default function getJSXPragmaInfo(options: Options): JSXPragmaInfo {
|
||||
+export { getJSXPragmaInfo as HACK };
|
||||
--- a/test/source-maps-test.ts
|
||||
+++ b/test/source-maps-test.ts
|
||||
@@ -26,0 +27 @@ var _a = require('./a'); var _a2 = _interopRequireDefault(_a);
|
||||
+delete result.sourceMap.ignoreList;
|
||||
EOF
|
||||
ERR=$?; if [ "$ERR" != "0" ]; then echo "Error: $ERR"; exit $ERR; fi
|
||||
npm_install esbuild-wasm@0.8.56 \
|
||||
&& minify_in_situ "src" \
|
||||
&& workaround src/parser/plugins/typescript.ts\
|
||||
&& workaround src/transformers/CJSImportTransformer.ts\
|
||||
&& rm -rf node_modules \
|
||||
&& npm_install \
|
||||
&& npm run clean \
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user