Compare commits
96 Commits
harmony-v3
...
harmony-v3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
91f8b57b3e | ||
|
|
3a2b737c42 | ||
|
|
4e12a6f740 | ||
|
|
b35dfc2599 | ||
|
|
9e1da9235e | ||
|
|
a5ffe2c23f | ||
|
|
9282e7b0c6 | ||
|
|
5229cb2b1b | ||
|
|
458e3e15f0 | ||
|
|
c615a1e80a | ||
|
|
10a938cb79 | ||
|
|
0f4278148d | ||
|
|
4956ad311b | ||
|
|
145874e504 | ||
|
|
f30375052b | ||
|
|
3e1a8598bf | ||
|
|
ef63de6968 | ||
|
|
2539fb8096 | ||
|
|
a556dd2dcb | ||
|
|
bd7be07c38 | ||
|
|
71ee91e716 | ||
|
|
e7334b4048 | ||
|
|
4f70d2e28c | ||
|
|
4b6ca5e742 | ||
|
|
f5c46db738 | ||
|
|
9306da3c58 | ||
|
|
1ac25fc032 | ||
|
|
fdbb1d09ef | ||
|
|
5f046c724b | ||
|
|
af0262b7e5 | ||
|
|
6b3aeff1d8 | ||
|
|
20e4f8277f | ||
|
|
f3a487a368 | ||
|
|
33ad0d258c | ||
|
|
5ea1da2d42 | ||
|
|
e77b6d525c | ||
|
|
2dde41615a | ||
|
|
8b69a3d18e | ||
|
|
d40950b741 | ||
|
|
a9eecd844f | ||
|
|
ed3032e52a | ||
|
|
7659ea1d2e | ||
|
|
52cc21d999 | ||
|
|
a938fe5e1f | ||
|
|
07a5a57336 | ||
|
|
bdeadffbf5 | ||
|
|
945db924fc | ||
|
|
087bce508a | ||
|
|
5e6f26445f | ||
|
|
fc7e33453f | ||
|
|
d052394621 | ||
|
|
4d5aeeddfb | ||
|
|
f0a99125ee | ||
|
|
1e4de2e6d3 | ||
|
|
ad139aa34d | ||
|
|
26be15f111 | ||
|
|
179f33f08a | ||
|
|
d260fe9018 | ||
|
|
96f9b8cba3 | ||
|
|
11afa816e3 | ||
|
|
8b4dcd8f3e | ||
|
|
285401ced8 | ||
|
|
9db4c42380 | ||
|
|
49f3de8397 | ||
|
|
94f93ad82d | ||
|
|
d1f085bce7 | ||
|
|
7b95b63ca1 | ||
|
|
94e5e00c03 | ||
|
|
dc6bcaa18e | ||
|
|
d58b184835 | ||
|
|
137e4c4753 | ||
|
|
b3a57ff019 | ||
|
|
3d5bc08185 | ||
|
|
0692435f01 | ||
|
|
b163b13a0b | ||
|
|
402954bdf3 | ||
|
|
f5931866e0 | ||
|
|
f67a6b0e43 | ||
|
|
471db8a717 | ||
|
|
8ba9e4e0da | ||
|
|
71556d00b5 | ||
|
|
8709753bfb | ||
|
|
db877e8729 | ||
|
|
11923e3ae8 | ||
|
|
62d1fbf645 | ||
|
|
343ea326c2 | ||
|
|
849ba79dee | ||
|
|
a298bcce02 | ||
|
|
daaf1273fa | ||
|
|
1c150c632f | ||
|
|
0a0f4f5591 | ||
|
|
931daa85bf | ||
|
|
00e4f7b3c1 | ||
|
|
11e63bc335 | ||
|
|
3fa862ce19 | ||
|
|
33405bb24b |
120
README.md
120
README.md
@@ -1,11 +1,11 @@
|
|||||||
uglify-es
|
uglify-es
|
||||||
=========
|
=========
|
||||||
|
|
||||||
**uglify-es** is an ECMAScript 2015 parser, minifier, compressor and beautifier toolkit.
|
A JavaScript parser, mangler/compressor and beautifier toolkit for ES6+.
|
||||||
|
|
||||||
#### Note:
|
#### Note:
|
||||||
- **The `uglify-es` API and CLI is compatible with `uglify-js@3.x`.**
|
- **`uglify-es` is API/CLI compatible with `uglify-js@3`.**
|
||||||
- **`uglify-es` is not backwards compatible with the `uglify-js@2.x` API and CLI.**
|
- **`uglify-es` is not backwards compatible with `uglify-js@2`.**
|
||||||
|
|
||||||
Install
|
Install
|
||||||
-------
|
-------
|
||||||
@@ -102,13 +102,14 @@ a double dash to prevent input files being used as option arguments:
|
|||||||
sequences.
|
sequences.
|
||||||
--config-file <file> Read `minify()` options from JSON file.
|
--config-file <file> Read `minify()` options from JSON file.
|
||||||
-d, --define <expr>[=value] Global definitions.
|
-d, --define <expr>[=value] Global definitions.
|
||||||
|
--ecma <version> Specifiy ECMAScript release: 5, 6, 7 or 8.
|
||||||
--ie8 Support non-standard Internet Explorer 8.
|
--ie8 Support non-standard Internet Explorer 8.
|
||||||
Equivalent to setting `ie8: true` in `minify()`
|
Equivalent to setting `ie8: true` in `minify()`
|
||||||
for `compress`, `mangle` and `output` options.
|
for `compress`, `mangle` and `output` options.
|
||||||
By default UglifyJS will not try to be IE-proof.
|
By default UglifyJS will not try to be IE-proof.
|
||||||
--keep-fnames Do not mangle/drop function names. Useful for
|
--keep-fnames Do not mangle/drop function names. Useful for
|
||||||
code relying on Function.prototype.name.
|
code relying on Function.prototype.name.
|
||||||
--name-cache File to hold mangled name mappings.
|
--name-cache <file> File to hold mangled name mappings.
|
||||||
--self Build UglifyJS as a library (implies --wrap UglifyJS)
|
--self Build UglifyJS as a library (implies --wrap UglifyJS)
|
||||||
--source-map [options] Enable source map/specify source map options:
|
--source-map [options] Enable source map/specify source map options:
|
||||||
`base` Path to compute relative paths from input files.
|
`base` Path to compute relative paths from input files.
|
||||||
@@ -380,7 +381,47 @@ var code = {
|
|||||||
var options = { toplevel: true };
|
var options = { toplevel: true };
|
||||||
var result = UglifyJS.minify(code, options);
|
var result = UglifyJS.minify(code, options);
|
||||||
console.log(result.code);
|
console.log(result.code);
|
||||||
// console.log(function(n,o){return n+o}(3,7));
|
// console.log(3+7);
|
||||||
|
```
|
||||||
|
|
||||||
|
The `nameCache` option:
|
||||||
|
```javascript
|
||||||
|
var options = {
|
||||||
|
mangle: {
|
||||||
|
toplevel: true,
|
||||||
|
},
|
||||||
|
nameCache: {}
|
||||||
|
};
|
||||||
|
var result1 = UglifyJS.minify({
|
||||||
|
"file1.js": "function add(first, second) { return first + second; }"
|
||||||
|
}, options);
|
||||||
|
var result2 = UglifyJS.minify({
|
||||||
|
"file2.js": "console.log(add(1 + 2, 3 + 4));"
|
||||||
|
}, options);
|
||||||
|
console.log(result1.code);
|
||||||
|
// function n(n,r){return n+r}
|
||||||
|
console.log(result2.code);
|
||||||
|
// console.log(n(3,7));
|
||||||
|
```
|
||||||
|
|
||||||
|
You may persist the name cache to the file system in the following way:
|
||||||
|
```javascript
|
||||||
|
var cacheFileName = "/tmp/cache.json";
|
||||||
|
var options = {
|
||||||
|
mangle: {
|
||||||
|
properties: true,
|
||||||
|
},
|
||||||
|
nameCache: JSON.parse(fs.readFileSync(cacheFileName, "utf8"))
|
||||||
|
};
|
||||||
|
fs.writeFileSync("part1.js", UglifyJS.minify({
|
||||||
|
"file1.js": fs.readFileSync("file1.js", "utf8"),
|
||||||
|
"file2.js": fs.readFileSync("file2.js", "utf8")
|
||||||
|
}, options).code, "utf8");
|
||||||
|
fs.writeFileSync("part2.js", UglifyJS.minify({
|
||||||
|
"file3.js": fs.readFileSync("file3.js", "utf8"),
|
||||||
|
"file4.js": fs.readFileSync("file4.js", "utf8")
|
||||||
|
}, options).code, "utf8");
|
||||||
|
fs.writeFileSync(cacheFileName, JSON.stringify(options.nameCache), "utf8");
|
||||||
```
|
```
|
||||||
|
|
||||||
An example of a combination of `minify()` options:
|
An example of a combination of `minify()` options:
|
||||||
@@ -433,6 +474,9 @@ if (result.error) throw result.error;
|
|||||||
|
|
||||||
## Minify options
|
## Minify options
|
||||||
|
|
||||||
|
- `ecma` (default `undefined`) - pass `5`, `6`, `7` or `8` to override `parse`,
|
||||||
|
`compress` and `output` options.
|
||||||
|
|
||||||
- `warnings` (default `false`) — pass `true` to return compressor warnings
|
- `warnings` (default `false`) — pass `true` to return compressor warnings
|
||||||
in `result.warnings`. Use the value `"verbose"` for more detailed warnings.
|
in `result.warnings`. Use the value `"verbose"` for more detailed warnings.
|
||||||
|
|
||||||
@@ -458,13 +502,19 @@ if (result.error) throw result.error;
|
|||||||
- `toplevel` (default `false`) - set to `true` if you wish to enable top level
|
- `toplevel` (default `false`) - set to `true` if you wish to enable top level
|
||||||
variable and function name mangling and to drop unused variables and functions.
|
variable and function name mangling and to drop unused variables and functions.
|
||||||
|
|
||||||
|
- `nameCache` (default `null`) - pass an empty object `{}` or a previously
|
||||||
|
used `nameCache` object if you wish to cache mangled variable and
|
||||||
|
property names across multiple invocations of `minify()`. Note: this is
|
||||||
|
a read/write property. `minify()` will read the name cache state of this
|
||||||
|
object and update it during minification so that it may be
|
||||||
|
reused or externally persisted by the user.
|
||||||
|
|
||||||
- `ie8` (default `false`) - set to `true` to support IE8.
|
- `ie8` (default `false`) - set to `true` to support IE8.
|
||||||
|
|
||||||
## Minify options structure
|
## Minify options structure
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
{
|
{
|
||||||
warnings: false,
|
|
||||||
parse: {
|
parse: {
|
||||||
// parse options
|
// parse options
|
||||||
},
|
},
|
||||||
@@ -484,8 +534,11 @@ if (result.error) throw result.error;
|
|||||||
sourceMap: {
|
sourceMap: {
|
||||||
// source map options
|
// source map options
|
||||||
},
|
},
|
||||||
|
ecma: 5, // specify one of: 5, 6, 7 or 8
|
||||||
|
nameCache: null, // or specify a name cache object
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
ie8: false,
|
ie8: false,
|
||||||
|
warnings: false,
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -539,6 +592,9 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
|||||||
## Parse options
|
## Parse options
|
||||||
|
|
||||||
- `bare_returns` (default `false`) -- support top level `return` statements
|
- `bare_returns` (default `false`) -- support top level `return` statements
|
||||||
|
- `ecma` (default: `8`) -- specify one of `5`, `6`, `7` or `8`. Note: this setting
|
||||||
|
is not presently enforced except for ES8 optional trailing commas in function
|
||||||
|
parameter lists and calls with `ecma` `8`.
|
||||||
- `html5_comments` (default `true`)
|
- `html5_comments` (default `true`)
|
||||||
- `shebang` (default `true`) -- support `#!command` as the first line
|
- `shebang` (default `true`) -- support `#!command` as the first line
|
||||||
|
|
||||||
@@ -590,9 +646,17 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
|||||||
|
|
||||||
- `evaluate` -- attempt to evaluate constant expressions
|
- `evaluate` -- attempt to evaluate constant expressions
|
||||||
|
|
||||||
|
- `arrows` (default `true`) -- convert ES5 style anonymous function expressions
|
||||||
|
to arrow functions if permissible by language semantics.
|
||||||
|
Note: `arrows` requires that the `ecma` compress option is set to `6` or greater.
|
||||||
|
|
||||||
- `booleans` -- various optimizations for boolean context, for example `!!a
|
- `booleans` -- various optimizations for boolean context, for example `!!a
|
||||||
? b : c → a ? b : c`
|
? b : c → a ? b : c`
|
||||||
|
|
||||||
|
- `typeofs` -- default `true`. Transforms `typeof foo == "undefined"` into
|
||||||
|
`foo === void 0`. Note: recommend to set this value to `false` for IE10 and
|
||||||
|
earlier versions due to known issues.
|
||||||
|
|
||||||
- `loops` -- optimizations for `do`, `while` and `for` loops when we can
|
- `loops` -- optimizations for `do`, `while` and `for` loops when we can
|
||||||
statically determine the condition
|
statically determine the condition
|
||||||
|
|
||||||
@@ -666,7 +730,7 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
|||||||
compressor from discarding function names. Useful for code relying on
|
compressor from discarding function names. Useful for code relying on
|
||||||
`Function.prototype.name`. See also: the `keep_fnames` [mangle option](#mangle).
|
`Function.prototype.name`. See also: the `keep_fnames` [mangle option](#mangle).
|
||||||
|
|
||||||
- `passes` -- default `1`. Number of times to run compress with a maximum of 3.
|
- `passes` -- default `1`. The maximum number of times to run compress.
|
||||||
In some cases more than one pass leads to further compressed code. Keep in
|
In some cases more than one pass leads to further compressed code. Keep in
|
||||||
mind more passes will take more time.
|
mind more passes will take more time.
|
||||||
|
|
||||||
@@ -678,6 +742,9 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
|||||||
annotation `/*@__PURE__*/` or `/*#__PURE__*/` immediately precedes the call. For
|
annotation `/*@__PURE__*/` or `/*#__PURE__*/` immediately precedes the call. For
|
||||||
example: `/*@__PURE__*/foo();`
|
example: `/*@__PURE__*/foo();`
|
||||||
|
|
||||||
|
- `ecma` -- default `5`. Pass `6` or greater to enable `compress` options that
|
||||||
|
will transform ES5 code into smaller ES6+ equivalent forms.
|
||||||
|
|
||||||
## Mangle options
|
## Mangle options
|
||||||
|
|
||||||
- `reserved` (default `[]`). Pass an array of identifiers that should be
|
- `reserved` (default `[]`). Pass an array of identifiers that should be
|
||||||
@@ -686,6 +753,8 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
|||||||
- `toplevel` (default `false`). Pass `true` to mangle names declared in the
|
- `toplevel` (default `false`). Pass `true` to mangle names declared in the
|
||||||
top level scope.
|
top level scope.
|
||||||
|
|
||||||
|
- `keep_classnames` (default `false`). Pass `true` to not mangle class names.
|
||||||
|
|
||||||
- `keep_fnames` (default `false`). Pass `true` to not mangle function names.
|
- `keep_fnames` (default `false`). Pass `true` to not mangle function names.
|
||||||
Useful for code relying on `Function.prototype.name`. See also: the `keep_fnames`
|
Useful for code relying on `Function.prototype.name`. See also: the `keep_fnames`
|
||||||
[compress option](#compress-options).
|
[compress option](#compress-options).
|
||||||
@@ -749,9 +818,12 @@ can pass additional arguments that control the code output:
|
|||||||
- `comments` (default `false`) -- pass `true` or `"all"` to preserve all
|
- `comments` (default `false`) -- pass `true` or `"all"` to preserve all
|
||||||
comments, `"some"` to preserve some comments, a regular expression string
|
comments, `"some"` to preserve some comments, a regular expression string
|
||||||
(e.g. `/^!/`) or a function.
|
(e.g. `/^!/`) or a function.
|
||||||
- `ecma` (default `5`) -- set output printing mode. This will only change the
|
- `ecma` (default `5`) -- set output printing mode. Set `ecma` to `6` or
|
||||||
output in direct control of the beautifier. Non-compatible features in the
|
greater to emit shorthand object properties - i.e.: `{a}` instead of `{a: a}`.
|
||||||
abstract syntax tree will still be outputted as is.
|
The `ecma` option will only change the output in direct control of the
|
||||||
|
beautifier. Non-compatible features in the abstract syntax tree will still
|
||||||
|
be output as is. For example: an `ecma` setting of `5` will **not** convert
|
||||||
|
ES6+ code to ES5.
|
||||||
- `indent_level` (default 4)
|
- `indent_level` (default 4)
|
||||||
- `indent_start` (default 0) -- prefix all lines by that many spaces
|
- `indent_start` (default 0) -- prefix all lines by that many spaces
|
||||||
- `inline_script` (default `false`) -- escape the slash in occurrences of
|
- `inline_script` (default `false`) -- escape the slash in occurrences of
|
||||||
@@ -829,7 +901,6 @@ when this flag is on:
|
|||||||
- `new Object()` → `{}`
|
- `new Object()` → `{}`
|
||||||
- `String(exp)` or `exp.toString()` → `"" + exp`
|
- `String(exp)` or `exp.toString()` → `"" + exp`
|
||||||
- `new Object/RegExp/Function/Error/Array (...)` → we discard the `new`
|
- `new Object/RegExp/Function/Error/Array (...)` → we discard the `new`
|
||||||
- `typeof foo == "undefined"` → `foo === void 0`
|
|
||||||
- `void 0` → `undefined` (if there is a variable named "undefined" in
|
- `void 0` → `undefined` (if there is a variable named "undefined" in
|
||||||
scope; we do it because the variable name will be mangled, typically
|
scope; we do it because the variable name will be mangled, typically
|
||||||
reduced to a single character)
|
reduced to a single character)
|
||||||
@@ -982,3 +1053,30 @@ in total it's a bit more than just using UglifyJS's own parser.
|
|||||||
|
|
||||||
[acorn]: https://github.com/ternjs/acorn
|
[acorn]: https://github.com/ternjs/acorn
|
||||||
[sm-spec]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k
|
[sm-spec]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k
|
||||||
|
|
||||||
|
### Uglify Fast Minify Mode
|
||||||
|
|
||||||
|
It's not well known, but whitespace removal and symbol mangling accounts
|
||||||
|
for 95% of the size reduction in minified code for most javascript - not
|
||||||
|
elaborate code transforms. One can simply disable `compress` to speed up
|
||||||
|
Uglify builds by 3 to 4 times. In this fast `mangle`-only mode Uglify has
|
||||||
|
comparable minify speeds and gzip sizes to
|
||||||
|
[`butternut`](https://www.npmjs.com/package/butternut):
|
||||||
|
|
||||||
|
| d3.js | minify size | gzip size | minify time (seconds) |
|
||||||
|
| --- | ---: | ---: | ---: |
|
||||||
|
| original | 451,131 | 108,733 | - |
|
||||||
|
| uglify-js@3.0.24 mangle=false, compress=false | 316,600 | 85,245 | 0.70 |
|
||||||
|
| uglify-js@3.0.24 mangle=true, compress=false | 220,216 | 72,730 | 1.13 |
|
||||||
|
| butternut@0.4.6 | 217,568 | 72,738 | 1.41 |
|
||||||
|
| uglify-js@3.0.24 mangle=true, compress=true | 212,511 | 71,560 | 3.36 |
|
||||||
|
| babili@0.1.4 | 210,713 | 72,140 | 12.64 |
|
||||||
|
|
||||||
|
To enable fast minify mode from the CLI use:
|
||||||
|
```
|
||||||
|
uglifyjs file.js -m
|
||||||
|
```
|
||||||
|
To enable fast minify mode with the API use:
|
||||||
|
```js
|
||||||
|
UglifyJS.minify(code, { compress: false, mangle: true });
|
||||||
|
```
|
||||||
|
|||||||
52
bin/uglifyjs
52
bin/uglifyjs
@@ -35,15 +35,16 @@ else if (process.argv.indexOf("options") >= 0) program.helpInformation = functio
|
|||||||
}
|
}
|
||||||
return text.join("\n");
|
return text.join("\n");
|
||||||
};
|
};
|
||||||
program.option("-p, --parse <options>", "Specify parser options.", parse_js("parse", true));
|
program.option("-p, --parse <options>", "Specify parser options.", parse_js());
|
||||||
program.option("-c, --compress [options]", "Enable compressor/specify compressor options.", parse_js("compress", true));
|
program.option("-c, --compress [options]", "Enable compressor/specify compressor options.", parse_js());
|
||||||
program.option("-m, --mangle [options]", "Mangle names/specify mangler options.", parse_js("mangle", true));
|
program.option("-m, --mangle [options]", "Mangle names/specify mangler options.", parse_js());
|
||||||
program.option("--mangle-props [options]", "Mangle properties/specify mangler options.", parse_js("mangle-props", true));
|
program.option("--mangle-props [options]", "Mangle properties/specify mangler options.", parse_js());
|
||||||
program.option("-b, --beautify [options]", "Beautify output/specify output options.", parse_js("beautify", true));
|
program.option("-b, --beautify [options]", "Beautify output/specify output options.", parse_js());
|
||||||
program.option("-o, --output <file>", "Output file (default STDOUT).");
|
program.option("-o, --output <file>", "Output file (default STDOUT).");
|
||||||
program.option("--comments [filter]", "Preserve copyright comments in the output.");
|
program.option("--comments [filter]", "Preserve copyright comments in the output.");
|
||||||
program.option("--config-file <file>", "Read minify() options from JSON file.");
|
program.option("--config-file <file>", "Read minify() options from JSON file.");
|
||||||
program.option("-d, --define <expr>[=value]", "Global definitions.", parse_js("define"));
|
program.option("-d, --define <expr>[=value]", "Global definitions.", parse_js("define"));
|
||||||
|
program.option("--ecma <version>", "Specifiy ECMAScript release: 5, 6, 7 or 8.");
|
||||||
program.option("--ie8", "Support non-standard Internet Explorer 8.");
|
program.option("--ie8", "Support non-standard Internet Explorer 8.");
|
||||||
program.option("--keep-fnames", "Do not mangle/drop function names. Useful for code relying on Function.prototype.name.");
|
program.option("--keep-fnames", "Do not mangle/drop function names. Useful for code relying on Function.prototype.name.");
|
||||||
program.option("--name-cache <file>", "File to hold mangled name mappings.");
|
program.option("--name-cache <file>", "File to hold mangled name mappings.");
|
||||||
@@ -73,6 +74,10 @@ if (!program.output && program.sourceMap && program.sourceMap.url != "inline") {
|
|||||||
options[name] = program[name];
|
options[name] = program[name];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if ("ecma" in program) {
|
||||||
|
if (program.ecma != (program.ecma | 0)) fatal("ERROR: ecma must be an integer");
|
||||||
|
options.ecma = program.ecma | 0;
|
||||||
|
}
|
||||||
if (program.beautify) {
|
if (program.beautify) {
|
||||||
options.output = typeof program.beautify == "object" ? program.beautify : {};
|
options.output = typeof program.beautify == "object" ? program.beautify : {};
|
||||||
if (!("beautify" in options.output)) {
|
if (!("beautify" in options.output)) {
|
||||||
@@ -106,17 +111,8 @@ if (program.mangleProps) {
|
|||||||
if (typeof options.mangle != "object") options.mangle = {};
|
if (typeof options.mangle != "object") options.mangle = {};
|
||||||
options.mangle.properties = program.mangleProps;
|
options.mangle.properties = program.mangleProps;
|
||||||
}
|
}
|
||||||
var cache;
|
|
||||||
if (program.nameCache) {
|
if (program.nameCache) {
|
||||||
cache = JSON.parse(read_file(program.nameCache, "{}"));
|
options.nameCache = JSON.parse(read_file(program.nameCache, "{}"));
|
||||||
if (options.mangle) {
|
|
||||||
if (typeof options.mangle != "object") options.mangle = {};
|
|
||||||
options.mangle.cache = to_cache("vars");
|
|
||||||
if (options.mangle.properties) {
|
|
||||||
if (typeof options.mangle.properties != "object") options.mangle.properties = {};
|
|
||||||
options.mangle.properties.cache = to_cache("props");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (program.output == "ast") {
|
if (program.output == "ast") {
|
||||||
options.output = {
|
options.output = {
|
||||||
@@ -266,9 +262,7 @@ function run() {
|
|||||||
print(result.code);
|
print(result.code);
|
||||||
}
|
}
|
||||||
if (program.nameCache) {
|
if (program.nameCache) {
|
||||||
fs.writeFileSync(program.nameCache, JSON.stringify(cache, function(key, value) {
|
fs.writeFileSync(program.nameCache, JSON.stringify(options.nameCache));
|
||||||
return value instanceof UglifyJS.Dictionary ? value.toObject() : value;
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
if (result.timings) for (var phase in result.timings) {
|
if (result.timings) for (var phase in result.timings) {
|
||||||
print_error("- " + phase + ": " + result.timings[phase].toFixed(3) + "s");
|
print_error("- " + phase + ": " + result.timings[phase].toFixed(3) + "s");
|
||||||
@@ -321,7 +315,7 @@ function read_file(path, default_value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function parse_js(flag, constants) {
|
function parse_js(flag) {
|
||||||
return function(value, options) {
|
return function(value, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
try {
|
try {
|
||||||
@@ -339,7 +333,7 @@ function parse_js(flag, constants) {
|
|||||||
if (node instanceof UglifyJS.AST_Assign) {
|
if (node instanceof UglifyJS.AST_Assign) {
|
||||||
var name = node.left.print_to_string();
|
var name = node.left.print_to_string();
|
||||||
var value = node.right;
|
var value = node.right;
|
||||||
if (!constants) {
|
if (flag) {
|
||||||
options[name] = value;
|
options[name] = value;
|
||||||
} else if (value instanceof UglifyJS.AST_Array) {
|
} else if (value instanceof UglifyJS.AST_Array) {
|
||||||
options[name] = value.elements.map(to_string);
|
options[name] = value.elements.map(to_string);
|
||||||
@@ -362,14 +356,18 @@ function parse_js(flag, constants) {
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
} catch(ex) {
|
} catch(ex) {
|
||||||
|
if (flag) {
|
||||||
|
fatal("Error parsing arguments for '" + flag + "': " + value);
|
||||||
|
} else {
|
||||||
options[value] = null;
|
options[value] = null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function parse_source_map() {
|
function parse_source_map() {
|
||||||
var parse = parse_js("sourceMap", true);
|
var parse = parse_js();
|
||||||
return function(value, options) {
|
return function(value, options) {
|
||||||
var hasContent = options && "content" in options;
|
var hasContent = options && "content" in options;
|
||||||
var settings = parse(value, options);
|
var settings = parse(value, options);
|
||||||
@@ -381,18 +379,6 @@ function parse_source_map() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function to_cache(key) {
|
|
||||||
if (cache[key]) {
|
|
||||||
cache[key].props = UglifyJS.Dictionary.fromObject(cache[key].props);
|
|
||||||
} else {
|
|
||||||
cache[key] = {
|
|
||||||
cname: -1,
|
|
||||||
props: new UglifyJS.Dictionary()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return cache[key];
|
|
||||||
}
|
|
||||||
|
|
||||||
function skip_key(key) {
|
function skip_key(key) {
|
||||||
return skip_keys.indexOf(key) >= 0;
|
return skip_keys.indexOf(key) >= 0;
|
||||||
}
|
}
|
||||||
|
|||||||
42
lib/ast.js
42
lib/ast.js
@@ -345,7 +345,7 @@ var AST_Toplevel = DEFNODE("Toplevel", "globals", {
|
|||||||
var AST_Expansion = DEFNODE("Expansion", "expression", {
|
var AST_Expansion = DEFNODE("Expansion", "expression", {
|
||||||
$documentation: "An expandible argument, such as ...rest, a splat, such as [1,2,...all], or an expansion in a variable declaration, such as var [first, ...rest] = list",
|
$documentation: "An expandible argument, such as ...rest, a splat, such as [1,2,...all], or an expansion in a variable declaration, such as var [first, ...rest] = list",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
expression: "AST_Symbol the thing to be expanded"
|
expression: "[AST_Node] the thing to be expanded"
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
_walk: function(visitor) {
|
||||||
var self = this;
|
var self = this;
|
||||||
@@ -446,7 +446,7 @@ var AST_PrefixedTemplateString = DEFNODE("PrefixedTemplateString", "template_str
|
|||||||
var AST_TemplateString = DEFNODE("TemplateString", "segments", {
|
var AST_TemplateString = DEFNODE("TemplateString", "segments", {
|
||||||
$documentation: "A template string literal",
|
$documentation: "A template string literal",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
segments: "[AST_TemplateSegment|AST_Expression]* One or more segments, starting with AST_TemplateSegment. AST_Expression may follow AST_TemplateSegment, but each AST_Expression must be followed by AST_TemplateSegment."
|
segments: "[AST_Node*] One or more segments, starting with AST_TemplateSegment. AST_Node may follow AST_TemplateSegment, but each AST_Node must be followed by AST_TemplateSegment."
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
_walk: function(visitor) {
|
||||||
return visitor._visit(this, function(){
|
return visitor._visit(this, function(){
|
||||||
@@ -629,11 +629,11 @@ var AST_Const = DEFNODE("Const", null, {
|
|||||||
$documentation: "A `const` statement"
|
$documentation: "A `const` statement"
|
||||||
}, AST_Definitions);
|
}, AST_Definitions);
|
||||||
|
|
||||||
var AST_NameImport = DEFNODE("NameImport", "foreign_name name", {
|
var AST_NameMapping = DEFNODE("NameMapping", "foreign_name name", {
|
||||||
$documentation: "The part of the import statement that imports names from a module.",
|
$documentation: "The part of the export/import statement that declare names from a module.",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
foreign_name: "[AST_SymbolImportForeign] The name being imported (as specified in the module)",
|
foreign_name: "[AST_SymbolExportForeign|AST_SymbolImportForeign] The name being exported/imported (as specified in the module)",
|
||||||
name: "[AST_SymbolImport] The name as it becomes available to this module."
|
name: "[AST_SymbolExport|AST_SymbolImport] The name as it is visible to this module."
|
||||||
},
|
},
|
||||||
_walk: function (visitor) {
|
_walk: function (visitor) {
|
||||||
return visitor._visit(this, function() {
|
return visitor._visit(this, function() {
|
||||||
@@ -647,7 +647,7 @@ var AST_Import = DEFNODE("Import", "imported_name imported_names module_name", {
|
|||||||
$documentation: "An `import` statement",
|
$documentation: "An `import` statement",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
imported_name: "[AST_SymbolImport] The name of the variable holding the module's default export.",
|
imported_name: "[AST_SymbolImport] The name of the variable holding the module's default export.",
|
||||||
imported_names: "[AST_NameImport*] The names of non-default imported variables",
|
imported_names: "[AST_NameMapping*] The names of non-default imported variables",
|
||||||
module_name: "[AST_String] String literal describing where this module came from",
|
module_name: "[AST_String] String literal describing where this module came from",
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
_walk: function(visitor) {
|
||||||
@@ -656,7 +656,7 @@ var AST_Import = DEFNODE("Import", "imported_name imported_names module_name", {
|
|||||||
this.imported_name._walk(visitor);
|
this.imported_name._walk(visitor);
|
||||||
}
|
}
|
||||||
if (this.imported_names) {
|
if (this.imported_names) {
|
||||||
this.imported_names.forEach(function (name_import) {
|
this.imported_names.forEach(function(name_import) {
|
||||||
name_import._walk(visitor);
|
name_import._walk(visitor);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -670,7 +670,7 @@ var AST_Export = DEFNODE("Export", "exported_definition exported_value is_defaul
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
exported_definition: "[AST_Defun|AST_Definitions|AST_DefClass?] An exported definition",
|
exported_definition: "[AST_Defun|AST_Definitions|AST_DefClass?] An exported definition",
|
||||||
exported_value: "[AST_Node?] An exported value",
|
exported_value: "[AST_Node?] An exported value",
|
||||||
exported_names: "[AST_NameImport*?] List of exported names",
|
exported_names: "[AST_NameMapping*?] List of exported names",
|
||||||
module_name: "[AST_String?] Name of the file to load exports from",
|
module_name: "[AST_String?] Name of the file to load exports from",
|
||||||
is_default: "[Boolean] Whether this is the default exported value of this module"
|
is_default: "[Boolean] Whether this is the default exported value of this module"
|
||||||
},
|
},
|
||||||
@@ -682,6 +682,14 @@ var AST_Export = DEFNODE("Export", "exported_definition exported_value is_defaul
|
|||||||
if (this.exported_value) {
|
if (this.exported_value) {
|
||||||
this.exported_value._walk(visitor);
|
this.exported_value._walk(visitor);
|
||||||
}
|
}
|
||||||
|
if (this.exported_names) {
|
||||||
|
this.exported_names.forEach(function(name_export) {
|
||||||
|
name_export._walk(visitor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (this.module_name) {
|
||||||
|
this.module_name._walk(visitor);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, AST_Statement);
|
}, AST_Statement);
|
||||||
@@ -996,7 +1004,7 @@ var AST_SymbolCatch = DEFNODE("SymbolCatch", null, {
|
|||||||
}, AST_SymbolBlockDeclaration);
|
}, AST_SymbolBlockDeclaration);
|
||||||
|
|
||||||
var AST_SymbolImport = DEFNODE("SymbolImport", null, {
|
var AST_SymbolImport = DEFNODE("SymbolImport", null, {
|
||||||
$documentation: "Symbol refering to an imported name",
|
$documentation: "Symbol referring to an imported name",
|
||||||
}, AST_SymbolBlockDeclaration);
|
}, AST_SymbolBlockDeclaration);
|
||||||
|
|
||||||
var AST_SymbolImportForeign = DEFNODE("SymbolImportForeign", null, {
|
var AST_SymbolImportForeign = DEFNODE("SymbolImportForeign", null, {
|
||||||
@@ -1018,6 +1026,14 @@ var AST_SymbolRef = DEFNODE("SymbolRef", null, {
|
|||||||
$documentation: "Reference to some symbol (not definition/declaration)",
|
$documentation: "Reference to some symbol (not definition/declaration)",
|
||||||
}, AST_Symbol);
|
}, AST_Symbol);
|
||||||
|
|
||||||
|
var AST_SymbolExport = DEFNODE("SymbolExport", null, {
|
||||||
|
$documentation: "Symbol referring to a name to export",
|
||||||
|
}, AST_SymbolRef);
|
||||||
|
|
||||||
|
var AST_SymbolExportForeign = DEFNODE("SymbolExportForeign", null, {
|
||||||
|
$documentation: "A symbol exported from this module, but it is used in the other module, and its real name is irrelevant for this module's purposes",
|
||||||
|
}, AST_Symbol);
|
||||||
|
|
||||||
var AST_LabelRef = DEFNODE("LabelRef", null, {
|
var AST_LabelRef = DEFNODE("LabelRef", null, {
|
||||||
$documentation: "Reference to a label symbol",
|
$documentation: "Reference to a label symbol",
|
||||||
}, AST_Symbol);
|
}, AST_Symbol);
|
||||||
@@ -1144,7 +1160,7 @@ TreeWalker.prototype = {
|
|||||||
if (!ret && descend) {
|
if (!ret && descend) {
|
||||||
descend.call(node);
|
descend.call(node);
|
||||||
}
|
}
|
||||||
this.pop(node);
|
this.pop();
|
||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
parent: function(n) {
|
parent: function(n) {
|
||||||
@@ -1163,8 +1179,8 @@ TreeWalker.prototype = {
|
|||||||
}
|
}
|
||||||
this.stack.push(node);
|
this.stack.push(node);
|
||||||
},
|
},
|
||||||
pop: function(node) {
|
pop: function() {
|
||||||
this.stack.pop();
|
var node = this.stack.pop();
|
||||||
if (node instanceof AST_Lambda || node instanceof AST_Class) {
|
if (node instanceof AST_Lambda || node instanceof AST_Class) {
|
||||||
this.directives = Object.getPrototypeOf(this.directives);
|
this.directives = Object.getPrototypeOf(this.directives);
|
||||||
}
|
}
|
||||||
|
|||||||
1260
lib/compress.js
1260
lib/compress.js
File diff suppressed because it is too large
Load Diff
@@ -27,14 +27,33 @@ function set_shorthand(name, options, keys) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function init_cache(cache) {
|
||||||
|
if (!cache) return;
|
||||||
|
if (!("cname" in cache)) cache.cname = -1;
|
||||||
|
if (!("props" in cache)) {
|
||||||
|
cache.props = new Dictionary();
|
||||||
|
} else if (!(cache.props instanceof Dictionary)) {
|
||||||
|
cache.props = Dictionary.fromObject(cache.props);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function to_json(cache) {
|
||||||
|
return {
|
||||||
|
cname: cache.cname,
|
||||||
|
props: cache.props.toObject()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function minify(files, options) {
|
function minify(files, options) {
|
||||||
var warn_function = AST_Node.warn_function;
|
var warn_function = AST_Node.warn_function;
|
||||||
try {
|
try {
|
||||||
options = defaults(options, {
|
options = defaults(options, {
|
||||||
compress: {},
|
compress: {},
|
||||||
|
ecma: undefined,
|
||||||
ie8: false,
|
ie8: false,
|
||||||
keep_fnames: false,
|
keep_fnames: false,
|
||||||
mangle: {},
|
mangle: {},
|
||||||
|
nameCache: null,
|
||||||
output: {},
|
output: {},
|
||||||
parse: {},
|
parse: {},
|
||||||
sourceMap: false,
|
sourceMap: false,
|
||||||
@@ -46,13 +65,14 @@ function minify(files, options) {
|
|||||||
var timings = options.timings && {
|
var timings = options.timings && {
|
||||||
start: Date.now()
|
start: Date.now()
|
||||||
};
|
};
|
||||||
|
set_shorthand("ecma", options, [ "parse", "compress", "output" ]);
|
||||||
set_shorthand("ie8", options, [ "compress", "mangle", "output" ]);
|
set_shorthand("ie8", options, [ "compress", "mangle", "output" ]);
|
||||||
set_shorthand("keep_fnames", options, [ "compress", "mangle" ]);
|
set_shorthand("keep_fnames", options, [ "compress", "mangle" ]);
|
||||||
set_shorthand("toplevel", options, [ "compress", "mangle" ]);
|
set_shorthand("toplevel", options, [ "compress", "mangle" ]);
|
||||||
set_shorthand("warnings", options, [ "compress" ]);
|
set_shorthand("warnings", options, [ "compress" ]);
|
||||||
if (options.mangle) {
|
if (options.mangle) {
|
||||||
options.mangle = defaults(options.mangle, {
|
options.mangle = defaults(options.mangle, {
|
||||||
cache: null,
|
cache: options.nameCache && (options.nameCache.vars || {}),
|
||||||
eval: false,
|
eval: false,
|
||||||
ie8: false,
|
ie8: false,
|
||||||
keep_classnames: false,
|
keep_classnames: false,
|
||||||
@@ -62,6 +82,16 @@ function minify(files, options) {
|
|||||||
safari10: false,
|
safari10: false,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}, true);
|
}, true);
|
||||||
|
if (options.nameCache && options.mangle.properties) {
|
||||||
|
if (typeof options.mangle.properties != "object") {
|
||||||
|
options.mangle.properties = {};
|
||||||
|
}
|
||||||
|
if (!("cache" in options.mangle.properties)) {
|
||||||
|
options.mangle.properties.cache = options.nameCache.props || {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
init_cache(options.mangle.cache);
|
||||||
|
init_cache(options.mangle.properties.cache);
|
||||||
}
|
}
|
||||||
if (options.sourceMap) {
|
if (options.sourceMap) {
|
||||||
options.sourceMap = defaults(options.sourceMap, {
|
options.sourceMap = defaults(options.sourceMap, {
|
||||||
@@ -155,6 +185,12 @@ function minify(files, options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (options.nameCache && options.mangle) {
|
||||||
|
if (options.mangle.cache) options.nameCache.vars = to_json(options.mangle.cache);
|
||||||
|
if (options.mangle.properties && options.mangle.properties.cache) {
|
||||||
|
options.nameCache.props = to_json(options.mangle.properties.cache);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (timings) {
|
if (timings) {
|
||||||
timings.end = Date.now();
|
timings.end = Date.now();
|
||||||
result.timings = {
|
result.timings = {
|
||||||
|
|||||||
@@ -533,6 +533,7 @@ function OutputStream(options) {
|
|||||||
use_asm = prev_use_asm;
|
use_asm = prev_use_asm;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
AST_Node.DEFMETHOD("_print", AST_Node.prototype.print);
|
||||||
|
|
||||||
AST_Node.DEFMETHOD("print_to_string", function(options){
|
AST_Node.DEFMETHOD("print_to_string", function(options){
|
||||||
var s = OutputStream(options);
|
var s = OutputStream(options);
|
||||||
@@ -672,6 +673,12 @@ function OutputStream(options) {
|
|||||||
&& this.operator !== "--";
|
&& this.operator !== "--";
|
||||||
});
|
});
|
||||||
|
|
||||||
|
PARENS(AST_Await, function(output){
|
||||||
|
var p = output.parent();
|
||||||
|
return p instanceof AST_PropAccess && p.expression === this
|
||||||
|
|| p instanceof AST_Call && p.expression === this;
|
||||||
|
});
|
||||||
|
|
||||||
PARENS(AST_Sequence, function(output){
|
PARENS(AST_Sequence, function(output){
|
||||||
var p = output.parent();
|
var p = output.parent();
|
||||||
return p instanceof AST_Call // (foo, bar)() or foo(1, (2, 3), 4)
|
return p instanceof AST_Call // (foo, bar)() or foo(1, (2, 3), 4)
|
||||||
@@ -738,14 +745,15 @@ function OutputStream(options) {
|
|||||||
// parens around it too, otherwise the call will be
|
// parens around it too, otherwise the call will be
|
||||||
// interpreted as passing the arguments to the upper New
|
// interpreted as passing the arguments to the upper New
|
||||||
// expression.
|
// expression.
|
||||||
try {
|
var parens = false;
|
||||||
this.walk(new TreeWalker(function(node){
|
this.walk(new TreeWalker(function(node) {
|
||||||
if (node instanceof AST_Call) throw p;
|
if (parens || node instanceof AST_Scope) return true;
|
||||||
}));
|
if (node instanceof AST_Call) {
|
||||||
} catch(ex) {
|
parens = true;
|
||||||
if (ex !== p) throw ex;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}));
|
||||||
|
return parens;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -978,12 +986,12 @@ function OutputStream(options) {
|
|||||||
AST_Lambda.DEFMETHOD("_do_print", function(output, nokeyword){
|
AST_Lambda.DEFMETHOD("_do_print", function(output, nokeyword){
|
||||||
var self = this;
|
var self = this;
|
||||||
if (!nokeyword) {
|
if (!nokeyword) {
|
||||||
if (this.async) {
|
if (self.async) {
|
||||||
output.print("async");
|
output.print("async");
|
||||||
output.space();
|
output.space();
|
||||||
}
|
}
|
||||||
output.print("function");
|
output.print("function");
|
||||||
if (this.is_generator) {
|
if (self.is_generator) {
|
||||||
output.star();
|
output.star();
|
||||||
}
|
}
|
||||||
if (self.name) {
|
if (self.name) {
|
||||||
@@ -1039,6 +1047,10 @@ function OutputStream(options) {
|
|||||||
parent instanceof AST_Unary ||
|
parent instanceof AST_Unary ||
|
||||||
(parent instanceof AST_Call && self === parent.expression);
|
(parent instanceof AST_Call && self === parent.expression);
|
||||||
if (needs_parens) { output.print("(") }
|
if (needs_parens) { output.print("(") }
|
||||||
|
if (self.async) {
|
||||||
|
output.print("async");
|
||||||
|
output.space();
|
||||||
|
}
|
||||||
if (self.argnames.length === 1 && self.argnames[0] instanceof AST_Symbol) {
|
if (self.argnames.length === 1 && self.argnames[0] instanceof AST_Symbol) {
|
||||||
self.argnames[0].print(output);
|
self.argnames[0].print(output);
|
||||||
} else {
|
} else {
|
||||||
@@ -1053,9 +1065,9 @@ function OutputStream(options) {
|
|||||||
output.print('=>');
|
output.print('=>');
|
||||||
output.space();
|
output.space();
|
||||||
if (self.body instanceof AST_Node) {
|
if (self.body instanceof AST_Node) {
|
||||||
this.body.print(output);
|
self.body.print(output);
|
||||||
} else {
|
} else {
|
||||||
print_bracketed(this.body, output);
|
print_bracketed(self.body, output);
|
||||||
}
|
}
|
||||||
if (needs_parens) { output.print(")") }
|
if (needs_parens) { output.print(")") }
|
||||||
});
|
});
|
||||||
@@ -1280,7 +1292,6 @@ function OutputStream(options) {
|
|||||||
name_import.print(output);
|
name_import.print(output);
|
||||||
if (i < self.imported_names.length - 1) {
|
if (i < self.imported_names.length - 1) {
|
||||||
output.print(",");
|
output.print(",");
|
||||||
output.space();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
output.space();
|
output.space();
|
||||||
@@ -1296,17 +1307,26 @@ function OutputStream(options) {
|
|||||||
output.semicolon();
|
output.semicolon();
|
||||||
});
|
});
|
||||||
|
|
||||||
DEFPRINT(AST_NameImport, function(self, output) {
|
DEFPRINT(AST_NameMapping, function(self, output) {
|
||||||
|
var is_import = output.parent() instanceof AST_Import;
|
||||||
var definition = self.name.definition();
|
var definition = self.name.definition();
|
||||||
var names_are_different =
|
var names_are_different =
|
||||||
(definition && definition.mangled_name || self.name.name) !==
|
(definition && definition.mangled_name || self.name.name) !==
|
||||||
self.foreign_name.name;
|
self.foreign_name.name;
|
||||||
if (names_are_different) {
|
if (names_are_different) {
|
||||||
|
if (is_import) {
|
||||||
output.print(self.foreign_name.name);
|
output.print(self.foreign_name.name);
|
||||||
|
} else {
|
||||||
|
self.name.print(output);
|
||||||
|
}
|
||||||
output.space();
|
output.space();
|
||||||
output.print("as");
|
output.print("as");
|
||||||
output.space();
|
output.space();
|
||||||
|
if (is_import) {
|
||||||
self.name.print(output);
|
self.name.print(output);
|
||||||
|
} else {
|
||||||
|
output.print(self.foreign_name.name);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
self.name.print(output);
|
self.name.print(output);
|
||||||
}
|
}
|
||||||
@@ -1320,24 +1340,20 @@ function OutputStream(options) {
|
|||||||
output.space();
|
output.space();
|
||||||
}
|
}
|
||||||
if (self.exported_names) {
|
if (self.exported_names) {
|
||||||
output.space();
|
|
||||||
|
|
||||||
if (self.exported_names.length === 1 && self.exported_names[0].name.name === "*") {
|
if (self.exported_names.length === 1 && self.exported_names[0].name.name === "*") {
|
||||||
self.exported_names[0].print(output);
|
self.exported_names[0].print(output);
|
||||||
} else {
|
} else {
|
||||||
output.print("{");
|
output.print("{");
|
||||||
self.exported_names.forEach(function (name_import, i) {
|
self.exported_names.forEach(function(name_export, i) {
|
||||||
output.space();
|
output.space();
|
||||||
name_import.print(output);
|
name_export.print(output);
|
||||||
if (i < self.exported_names.length - 1) {
|
if (i < self.exported_names.length - 1) {
|
||||||
output.print(",");
|
output.print(",");
|
||||||
output.space();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
output.space();
|
output.space();
|
||||||
output.print("}");
|
output.print("}");
|
||||||
}
|
}
|
||||||
output.space();
|
|
||||||
}
|
}
|
||||||
else if (self.exported_value) {
|
else if (self.exported_value) {
|
||||||
self.exported_value.print(output);
|
self.exported_value.print(output);
|
||||||
@@ -1354,19 +1370,17 @@ function OutputStream(options) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
function parenthesize_for_noin(node, output, noin) {
|
function parenthesize_for_noin(node, output, noin) {
|
||||||
if (!noin) node.print(output);
|
var parens = false;
|
||||||
else try {
|
|
||||||
// need to take some precautions here:
|
// need to take some precautions here:
|
||||||
// https://github.com/mishoo/UglifyJS2/issues/60
|
// https://github.com/mishoo/UglifyJS2/issues/60
|
||||||
node.walk(new TreeWalker(function(node){
|
if (noin) node.walk(new TreeWalker(function(node) {
|
||||||
if (node instanceof AST_Binary && node.operator == "in")
|
if (parens || node instanceof AST_Scope) return true;
|
||||||
throw output;
|
if (node instanceof AST_Binary && node.operator == "in") {
|
||||||
}));
|
parens = true;
|
||||||
node.print(output);
|
return true;
|
||||||
} catch(ex) {
|
|
||||||
if (ex !== output) throw ex;
|
|
||||||
node.print(output, true);
|
|
||||||
}
|
}
|
||||||
|
}));
|
||||||
|
node.print(output, parens);
|
||||||
};
|
};
|
||||||
|
|
||||||
DEFPRINT(AST_VarDef, function(self, output){
|
DEFPRINT(AST_VarDef, function(self, output){
|
||||||
@@ -1386,6 +1400,9 @@ function OutputStream(options) {
|
|||||||
self.expression.print(output);
|
self.expression.print(output);
|
||||||
if (self instanceof AST_New && !need_constructor_parens(self, output))
|
if (self instanceof AST_New && !need_constructor_parens(self, output))
|
||||||
return;
|
return;
|
||||||
|
if (self.expression instanceof AST_Lambda) {
|
||||||
|
output.add_mapping(self.start);
|
||||||
|
}
|
||||||
output.with_parens(function(){
|
output.with_parens(function(){
|
||||||
self.args.forEach(function(expr, i){
|
self.args.forEach(function(expr, i){
|
||||||
if (i) output.comma();
|
if (i) output.comma();
|
||||||
@@ -1425,6 +1442,13 @@ function OutputStream(options) {
|
|||||||
DEFPRINT(AST_Dot, function(self, output){
|
DEFPRINT(AST_Dot, function(self, output){
|
||||||
var expr = self.expression;
|
var expr = self.expression;
|
||||||
expr.print(output);
|
expr.print(output);
|
||||||
|
var prop = self.property;
|
||||||
|
if (output.option("ie8") && RESERVED_WORDS(prop)) {
|
||||||
|
output.print("[");
|
||||||
|
output.add_mapping(self.end);
|
||||||
|
output.print_string(prop);
|
||||||
|
output.print("]");
|
||||||
|
} else {
|
||||||
if (expr instanceof AST_Number && expr.getValue() >= 0) {
|
if (expr instanceof AST_Number && expr.getValue() >= 0) {
|
||||||
if (!/[xa-f.)]/i.test(output.last())) {
|
if (!/[xa-f.)]/i.test(output.last())) {
|
||||||
output.print(".");
|
output.print(".");
|
||||||
@@ -1433,7 +1457,8 @@ function OutputStream(options) {
|
|||||||
output.print(".");
|
output.print(".");
|
||||||
// the name after dot would be mapped about here.
|
// the name after dot would be mapped about here.
|
||||||
output.add_mapping(self.end);
|
output.add_mapping(self.end);
|
||||||
output.print_name(self.property);
|
output.print_name(prop);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_Sub, function(self, output){
|
DEFPRINT(AST_Sub, function(self, output){
|
||||||
self.expression.print(output);
|
self.expression.print(output);
|
||||||
|
|||||||
245
lib/parse.js
245
lib/parse.js
@@ -509,8 +509,11 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
}
|
}
|
||||||
var content = "", raw = "", ch, tok;
|
var content = "", raw = "", ch, tok;
|
||||||
next(true, true);
|
next(true, true);
|
||||||
while ((ch = next(true, true)) !== "`") {
|
while ((ch = next(true, true)) != "`") {
|
||||||
if (ch === "$" && peek() === "{") {
|
if (ch == "\r") {
|
||||||
|
if (peek() == "\n") ++S.pos;
|
||||||
|
ch = "\n";
|
||||||
|
} else if (ch == "$" && peek() == "{") {
|
||||||
next(true, true);
|
next(true, true);
|
||||||
S.brace_counter++;
|
S.brace_counter++;
|
||||||
tok = token(begin ? "template_head" : "template_substitution", content);
|
tok = token(begin ? "template_head" : "template_substitution", content);
|
||||||
@@ -521,7 +524,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
raw += ch;
|
raw += ch;
|
||||||
if (ch === "\\") {
|
if (ch == "\\") {
|
||||||
var tmp = S.pos;
|
var tmp = S.pos;
|
||||||
ch = read_escaped_char();
|
ch = read_escaped_char();
|
||||||
raw += S.text.substr(tmp, S.pos - tmp);
|
raw += S.text.substr(tmp, S.pos - tmp);
|
||||||
@@ -856,6 +859,7 @@ function parse($TEXT, options) {
|
|||||||
|
|
||||||
options = defaults(options, {
|
options = defaults(options, {
|
||||||
bare_returns : false,
|
bare_returns : false,
|
||||||
|
ecma : 8,
|
||||||
expression : false,
|
expression : false,
|
||||||
filename : null,
|
filename : null,
|
||||||
html5_comments : true,
|
html5_comments : true,
|
||||||
@@ -1229,9 +1233,12 @@ function parse($TEXT, options) {
|
|||||||
var is_in = is("operator", "in");
|
var is_in = is("operator", "in");
|
||||||
var is_of = is("name", "of");
|
var is_of = is("name", "of");
|
||||||
if (is_in || is_of) {
|
if (is_in || is_of) {
|
||||||
if ((init instanceof AST_Definitions) &&
|
if (init instanceof AST_Definitions) {
|
||||||
init.definitions.length > 1)
|
if (init.definitions.length > 1)
|
||||||
croak("Only one variable declaration allowed in for..in loop");
|
croak("Only one variable declaration allowed in for..in loop", init.start.line, init.start.col, init.start.pos);
|
||||||
|
} else if (!(is_assignable(init) || (init = to_destructuring(init)) instanceof AST_Destructuring)) {
|
||||||
|
croak("Invalid left-hand side in for..in loop", init.start.line, init.start.col, init.start.pos);
|
||||||
|
}
|
||||||
next();
|
next();
|
||||||
if (is_in) {
|
if (is_in) {
|
||||||
return for_in(init);
|
return for_in(init);
|
||||||
@@ -1281,18 +1288,19 @@ function parse($TEXT, options) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var arrow_function = function(start, argnames) {
|
var arrow_function = function(start, argnames, is_async) {
|
||||||
if (S.token.nlb) {
|
if (S.token.nlb) {
|
||||||
croak("Unexpected newline before arrow (=>)");
|
croak("Unexpected newline before arrow (=>)");
|
||||||
}
|
}
|
||||||
|
|
||||||
expect_token("arrow", "=>");
|
expect_token("arrow", "=>");
|
||||||
|
|
||||||
var body = _function_body(is("punc", "{"));
|
var body = _function_body(is("punc", "{"), false, is_async);
|
||||||
|
|
||||||
return new AST_Arrow({
|
return new AST_Arrow({
|
||||||
start : start,
|
start : start,
|
||||||
end : body.end,
|
end : body.end,
|
||||||
|
async : is_async,
|
||||||
argnames : argnames,
|
argnames : argnames,
|
||||||
body : body
|
body : body
|
||||||
});
|
});
|
||||||
@@ -1385,22 +1393,20 @@ function parse($TEXT, options) {
|
|||||||
|
|
||||||
function parameters() {
|
function parameters() {
|
||||||
var start = S.token;
|
var start = S.token;
|
||||||
var first = true;
|
|
||||||
var params = [];
|
var params = [];
|
||||||
var used_parameters = track_used_binding_identifiers(true, S.input.has_directive("use strict"));
|
var used_parameters = track_used_binding_identifiers(true, S.input.has_directive("use strict"));
|
||||||
|
|
||||||
expect("(");
|
expect("(");
|
||||||
|
|
||||||
while (!is("punc", ")")) {
|
while (!is("punc", ")")) {
|
||||||
if (first) {
|
|
||||||
first = false;
|
|
||||||
} else {
|
|
||||||
expect(",");
|
|
||||||
}
|
|
||||||
|
|
||||||
var param = parameter(used_parameters);
|
var param = parameter(used_parameters);
|
||||||
params.push(param);
|
params.push(param);
|
||||||
|
|
||||||
|
if (!is("punc", ")")) {
|
||||||
|
expect(",");
|
||||||
|
if (is("punc", ")") && options.ecma < 8) unexpected();
|
||||||
|
}
|
||||||
|
|
||||||
if (param instanceof AST_Expansion) {
|
if (param instanceof AST_Expansion) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1616,25 +1622,40 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function params_or_seq_() {
|
function params_or_seq_(allow_arrows, maybe_sequence) {
|
||||||
var first = true;
|
var spread_token;
|
||||||
|
var invalid_sequence;
|
||||||
|
var trailing_comma;
|
||||||
var a = [];
|
var a = [];
|
||||||
|
expect("(");
|
||||||
while (!is("punc", ")")) {
|
while (!is("punc", ")")) {
|
||||||
if (first) first = false; else expect(",");
|
if (spread_token) unexpected(spread_token);
|
||||||
if (is("expand", "...")) {
|
if (is("expand", "...")) {
|
||||||
var spread_token = S.token;
|
spread_token = S.token;
|
||||||
|
if (maybe_sequence) invalid_sequence = S.token;
|
||||||
next();
|
next();
|
||||||
a.push(new AST_Expansion({
|
a.push(new AST_Expansion({
|
||||||
start: prev(),
|
start: prev(),
|
||||||
expression: expression(),
|
expression: expression(),
|
||||||
end: S.token,
|
end: S.token,
|
||||||
}));
|
}));
|
||||||
if (!is("punc", ")")) {
|
|
||||||
unexpected(spread_token);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
a.push(expression());
|
a.push(expression());
|
||||||
}
|
}
|
||||||
|
if (!is("punc", ")")) {
|
||||||
|
expect(",");
|
||||||
|
if (is("punc", ")")) {
|
||||||
|
if (options.ecma < 8) unexpected();
|
||||||
|
trailing_comma = prev();
|
||||||
|
if (maybe_sequence) invalid_sequence = trailing_comma;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect(")");
|
||||||
|
if (allow_arrows && is("arrow", "=>")) {
|
||||||
|
if (spread_token && trailing_comma) unexpected(trailing_comma);
|
||||||
|
} else if (invalid_sequence) {
|
||||||
|
unexpected(invalid_sequence);
|
||||||
}
|
}
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
@@ -1882,7 +1903,7 @@ function parse($TEXT, options) {
|
|||||||
var newexp = expr_atom(false), args;
|
var newexp = expr_atom(false), args;
|
||||||
if (is("punc", "(")) {
|
if (is("punc", "(")) {
|
||||||
next();
|
next();
|
||||||
args = expr_list(")");
|
args = expr_list(")", options.ecma >= 8);
|
||||||
} else {
|
} else {
|
||||||
args = [];
|
args = [];
|
||||||
}
|
}
|
||||||
@@ -1989,21 +2010,24 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var expr_atom = function(allow_calls) {
|
var expr_atom = function(allow_calls, allow_arrows) {
|
||||||
if (is("operator", "new")) {
|
if (is("operator", "new")) {
|
||||||
return new_(allow_calls);
|
return new_(allow_calls);
|
||||||
}
|
}
|
||||||
var start = S.token;
|
var start = S.token;
|
||||||
|
var async = is("name", "async") && as_atom_node();
|
||||||
if (is("punc")) {
|
if (is("punc")) {
|
||||||
switch (start.value) {
|
switch (S.token.value) {
|
||||||
case "(":
|
case "(":
|
||||||
next();
|
if (async && !allow_calls) break;
|
||||||
var exprs = params_or_seq_();
|
var exprs = params_or_seq_(allow_arrows, !async);
|
||||||
expect(")");
|
if (allow_arrows && is("arrow", "=>")) {
|
||||||
if (is("arrow", "=>")) {
|
return arrow_function(start, exprs.map(to_fun_args), !!async);
|
||||||
return arrow_function(start, exprs.map(to_fun_args));
|
|
||||||
}
|
}
|
||||||
var ex = exprs.length == 1 ? exprs[0] : new AST_Sequence({
|
var ex = async ? new AST_Call({
|
||||||
|
expression: async,
|
||||||
|
args: exprs
|
||||||
|
}) : exprs.length == 1 ? exprs[0] : new AST_Sequence({
|
||||||
expressions: exprs
|
expressions: exprs
|
||||||
});
|
});
|
||||||
ex.start = start;
|
ex.start = start;
|
||||||
@@ -2012,25 +2036,27 @@ function parse($TEXT, options) {
|
|||||||
case "[":
|
case "[":
|
||||||
return subscripts(array_(), allow_calls);
|
return subscripts(array_(), allow_calls);
|
||||||
case "{":
|
case "{":
|
||||||
return subscripts(object_or_object_destructuring_(), allow_calls);
|
return subscripts(object_or_destructuring_(), allow_calls);
|
||||||
}
|
}
|
||||||
unexpected();
|
if (!async) unexpected();
|
||||||
}
|
}
|
||||||
if (is("name", "async") && is_token(peek(), "keyword", "function")) {
|
if (allow_arrows && is("name") && is_token(peek(), "arrow")) {
|
||||||
|
var param = new AST_SymbolFunarg({
|
||||||
|
name: S.token.value,
|
||||||
|
start: start,
|
||||||
|
end: start,
|
||||||
|
});
|
||||||
next();
|
next();
|
||||||
next();
|
return arrow_function(start, [param], !!async);
|
||||||
var func = function_(AST_Function, false, true);
|
|
||||||
func.start = start;
|
|
||||||
func.end = prev();
|
|
||||||
return subscripts(func, allow_calls);
|
|
||||||
}
|
}
|
||||||
if (is("keyword", "function")) {
|
if (is("keyword", "function")) {
|
||||||
next();
|
next();
|
||||||
var func = function_(AST_Function);
|
var func = function_(AST_Function, false, !!async);
|
||||||
func.start = start;
|
func.start = start;
|
||||||
func.end = prev();
|
func.end = prev();
|
||||||
return subscripts(func, allow_calls);
|
return subscripts(func, allow_calls);
|
||||||
}
|
}
|
||||||
|
if (async) return subscripts(async, allow_calls);
|
||||||
if (is("keyword", "class")) {
|
if (is("keyword", "class")) {
|
||||||
next();
|
next();
|
||||||
var cls = class_(AST_ClassExpression);
|
var cls = class_(AST_ClassExpression);
|
||||||
@@ -2109,7 +2135,7 @@ function parse($TEXT, options) {
|
|||||||
return function_(AST_Accessor, is_generator, is_async);
|
return function_(AST_Accessor, is_generator, is_async);
|
||||||
});
|
});
|
||||||
|
|
||||||
var object_or_object_destructuring_ = embed_tokens(function() {
|
var object_or_destructuring_ = embed_tokens(function object_or_destructuring_() {
|
||||||
var start = S.token, first = true, a = [];
|
var start = S.token, first = true, a = [];
|
||||||
expect("{");
|
expect("{");
|
||||||
while (!is("punc", "}")) {
|
while (!is("punc", "}")) {
|
||||||
@@ -2231,7 +2257,7 @@ function parse($TEXT, options) {
|
|||||||
property_token = S.token;
|
property_token = S.token;
|
||||||
name = as_property_name();
|
name = as_property_name();
|
||||||
}
|
}
|
||||||
if (name === "async" && !is("punc", "(")) {
|
if (name === "async" && !is("punc", "(") && !is("punc", ",") && !is("punc", "}")) {
|
||||||
is_async = true;
|
is_async = true;
|
||||||
property_token = S.token;
|
property_token = S.token;
|
||||||
name = as_property_name();
|
name = as_property_name();
|
||||||
@@ -2302,7 +2328,7 @@ function parse($TEXT, options) {
|
|||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
|
|
||||||
imported_names = import_names(true);
|
imported_names = map_names(true);
|
||||||
|
|
||||||
if (imported_names || imported_name) {
|
if (imported_names || imported_name) {
|
||||||
expect_token("name", "from");
|
expect_token("name", "from");
|
||||||
@@ -2326,26 +2352,40 @@ function parse($TEXT, options) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function import_name() {
|
function map_name(is_import) {
|
||||||
|
function make_symbol(type) {
|
||||||
|
return new type({
|
||||||
|
name: as_property_name(),
|
||||||
|
start: prev(),
|
||||||
|
end: prev()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var foreign_type = is_import ? AST_SymbolImportForeign : AST_SymbolExportForeign;
|
||||||
|
var type = is_import ? AST_SymbolImport : AST_SymbolExport;
|
||||||
var start = S.token;
|
var start = S.token;
|
||||||
var foreign_name;
|
var foreign_name;
|
||||||
var name;
|
var name;
|
||||||
|
|
||||||
if (peek().value === "as" && peek().type === "name") {
|
if (is_import) {
|
||||||
foreign_name = as_symbol(AST_SymbolImportForeign);
|
foreign_name = make_symbol(foreign_type);
|
||||||
|
} else {
|
||||||
|
name = make_symbol(type);
|
||||||
|
}
|
||||||
|
if (is("name", "as")) {
|
||||||
next(); // The "as" word
|
next(); // The "as" word
|
||||||
|
if (is_import) {
|
||||||
|
name = make_symbol(type);
|
||||||
|
} else {
|
||||||
|
foreign_name = make_symbol(foreign_type);
|
||||||
}
|
}
|
||||||
name = as_symbol(AST_SymbolImport);
|
} else if (is_import) {
|
||||||
|
name = new type(foreign_name);
|
||||||
if (foreign_name === undefined) {
|
} else {
|
||||||
foreign_name = new AST_SymbolImportForeign({
|
foreign_name = new foreign_type(name);
|
||||||
name: name.name,
|
|
||||||
start: name.start,
|
|
||||||
end: name.end,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new AST_NameImport({
|
return new AST_NameMapping({
|
||||||
start: start,
|
start: start,
|
||||||
foreign_name: foreign_name,
|
foreign_name: foreign_name,
|
||||||
name: name,
|
name: name,
|
||||||
@@ -2353,26 +2393,26 @@ function parse($TEXT, options) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function import_nameAsterisk(name) {
|
function map_nameAsterisk(is_import, name) {
|
||||||
|
var foreign_type = is_import ? AST_SymbolImportForeign : AST_SymbolExportForeign;
|
||||||
|
var type = is_import ? AST_SymbolImport : AST_SymbolExport;
|
||||||
var start = S.token;
|
var start = S.token;
|
||||||
var foreign_name;
|
var foreign_name;
|
||||||
|
|
||||||
|
|
||||||
var end = prev();
|
var end = prev();
|
||||||
|
|
||||||
name = name || new AST_SymbolImport({
|
name = name || new type({
|
||||||
name: '*',
|
name: '*',
|
||||||
start: start,
|
start: start,
|
||||||
end: end,
|
end: end,
|
||||||
});
|
});
|
||||||
|
|
||||||
foreign_name = new AST_SymbolImportForeign({
|
foreign_name = new foreign_type({
|
||||||
name: '*',
|
name: '*',
|
||||||
start: start,
|
start: start,
|
||||||
end: end,
|
end: end,
|
||||||
});
|
});
|
||||||
|
|
||||||
return new AST_NameImport({
|
return new AST_NameMapping({
|
||||||
start: start,
|
start: start,
|
||||||
foreign_name: foreign_name,
|
foreign_name: foreign_name,
|
||||||
name: name,
|
name: name,
|
||||||
@@ -2380,13 +2420,13 @@ function parse($TEXT, options) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function import_names(allow_as) {
|
function map_names(is_import) {
|
||||||
var names;
|
var names;
|
||||||
if (is("punc", "{")) {
|
if (is("punc", "{")) {
|
||||||
next();
|
next();
|
||||||
names = [];
|
names = [];
|
||||||
while (!is("punc", "}")) {
|
while (!is("punc", "}")) {
|
||||||
names.push(import_name());
|
names.push(map_name(is_import));
|
||||||
if (is("punc", ",")) {
|
if (is("punc", ",")) {
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
@@ -2395,11 +2435,11 @@ function parse($TEXT, options) {
|
|||||||
} else if (is("operator", "*")) {
|
} else if (is("operator", "*")) {
|
||||||
var name;
|
var name;
|
||||||
next();
|
next();
|
||||||
if (allow_as && is("name", "as")) {
|
if (is_import && is("name", "as")) {
|
||||||
next(); // The "as" word
|
next(); // The "as" word
|
||||||
name = as_symbol(AST_SymbolImportForeign);
|
name = as_symbol(AST_SymbolImportForeign);
|
||||||
}
|
}
|
||||||
names = [import_nameAsterisk(name)];
|
names = [map_nameAsterisk(is_import, name)];
|
||||||
}
|
}
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
@@ -2407,17 +2447,12 @@ function parse($TEXT, options) {
|
|||||||
function export_() {
|
function export_() {
|
||||||
var start = S.token;
|
var start = S.token;
|
||||||
var is_default;
|
var is_default;
|
||||||
var exported_value;
|
|
||||||
var exported_definition;
|
|
||||||
var exported_names;
|
var exported_names;
|
||||||
|
|
||||||
if (is("keyword", "default")) {
|
if (is("keyword", "default")) {
|
||||||
is_default = true;
|
is_default = true;
|
||||||
next();
|
next();
|
||||||
} else {
|
} else if (exported_names = map_names(false)) {
|
||||||
exported_names = import_names(false);
|
|
||||||
|
|
||||||
if (exported_names) {
|
|
||||||
if (is("name", "from")) {
|
if (is("name", "from")) {
|
||||||
next();
|
next();
|
||||||
|
|
||||||
@@ -2448,31 +2483,24 @@ function parse($TEXT, options) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
var is_definition = is("keyword", "var") || is("keyword", "let") || is("keyword", "const");
|
var node;
|
||||||
if (is_definition) {
|
var exported_value;
|
||||||
if (is_default) unexpected();
|
var exported_definition;
|
||||||
exported_definition = statement();
|
if (is("punc", "{")
|
||||||
} else if (is("keyword", "class")) {
|
|| is_default
|
||||||
var cls = expr_atom(false);
|
&& (is("keyword", "class") || is("keyword", "function"))
|
||||||
if (cls.name) {
|
&& is_token(peek(), "punc")) {
|
||||||
cls.name = new AST_SymbolDefClass(cls.name);
|
|
||||||
exported_definition = new AST_DefClass(cls);
|
|
||||||
} else {
|
|
||||||
exported_value = cls;
|
|
||||||
}
|
|
||||||
} else if (is("keyword", "function")) {
|
|
||||||
var func = expr_atom(false);
|
|
||||||
if (func.name) {
|
|
||||||
func.name = new AST_SymbolDefun(func.name);
|
|
||||||
exported_definition = new AST_Defun(func);
|
|
||||||
} else {
|
|
||||||
exported_value = func;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
exported_value = expression(false);
|
exported_value = expression(false);
|
||||||
semicolon();
|
semicolon();
|
||||||
|
} else if ((node = statement()) instanceof AST_Definitions && is_default) {
|
||||||
|
unexpected(node.start);
|
||||||
|
} else if (node instanceof AST_Definitions || node instanceof AST_Defun || node instanceof AST_DefClass) {
|
||||||
|
exported_definition = node;
|
||||||
|
} else if (node instanceof AST_SimpleStatement) {
|
||||||
|
exported_value = node.body;
|
||||||
|
} else {
|
||||||
|
unexpected(node.start);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new AST_Export({
|
return new AST_Export({
|
||||||
@@ -2598,11 +2626,9 @@ function parse($TEXT, options) {
|
|||||||
return expr;
|
return expr;
|
||||||
};
|
};
|
||||||
|
|
||||||
var call_args = embed_tokens(function call_args() {
|
var call_args = embed_tokens(function _call_args() {
|
||||||
var first = true;
|
|
||||||
var args = [];
|
var args = [];
|
||||||
while (!is("punc", ")")) {
|
while (!is("punc", ")")) {
|
||||||
if (first) first = false; else expect(",");
|
|
||||||
if (is("expand", "...")) {
|
if (is("expand", "...")) {
|
||||||
next();
|
next();
|
||||||
args.push(new AST_Expansion({
|
args.push(new AST_Expansion({
|
||||||
@@ -2612,12 +2638,16 @@ function parse($TEXT, options) {
|
|||||||
} else {
|
} else {
|
||||||
args.push(expression(false));
|
args.push(expression(false));
|
||||||
}
|
}
|
||||||
|
if (!is("punc", ")")) {
|
||||||
|
expect(",");
|
||||||
|
if (is("punc", ")") && options.ecma < 8) unexpected();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
next();
|
next();
|
||||||
return args;
|
return args;
|
||||||
});
|
});
|
||||||
|
|
||||||
var maybe_unary = function(allow_calls) {
|
var maybe_unary = function(allow_calls, allow_arrows) {
|
||||||
var start = S.token;
|
var start = S.token;
|
||||||
if (start.type == "name" && start.value == "await") {
|
if (start.type == "name" && start.value == "await") {
|
||||||
if (is_in_async()) {
|
if (is_in_async()) {
|
||||||
@@ -2635,8 +2665,9 @@ function parse($TEXT, options) {
|
|||||||
ex.end = prev();
|
ex.end = prev();
|
||||||
return ex;
|
return ex;
|
||||||
}
|
}
|
||||||
var val = expr_atom(allow_calls);
|
var val = expr_atom(allow_calls, allow_arrows);
|
||||||
while (is("operator") && UNARY_POSTFIX(S.token.value) && !S.token.nlb) {
|
while (is("operator") && UNARY_POSTFIX(S.token.value) && !S.token.nlb) {
|
||||||
|
if (val instanceof AST_Arrow) unexpected();
|
||||||
val = make_unary(AST_UnaryPostfix, S.token, val);
|
val = make_unary(AST_UnaryPostfix, S.token, val);
|
||||||
val.start = start;
|
val.start = start;
|
||||||
val.end = S.token;
|
val.end = S.token;
|
||||||
@@ -2684,7 +2715,7 @@ function parse($TEXT, options) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function expr_ops(no_in) {
|
function expr_ops(no_in) {
|
||||||
return expr_op(maybe_unary(true), 0, no_in);
|
return expr_op(maybe_unary(true, true), 0, no_in);
|
||||||
};
|
};
|
||||||
|
|
||||||
var maybe_conditional = function(no_in) {
|
var maybe_conditional = function(no_in) {
|
||||||
@@ -2765,22 +2796,6 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (start.type == "punc" && start.value == "(" && peek().value == ")") {
|
|
||||||
next();
|
|
||||||
next();
|
|
||||||
return arrow_function(start, []);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is("name") && is_token(peek(), "arrow")) {
|
|
||||||
var param = new AST_SymbolFunarg({
|
|
||||||
name: start.value,
|
|
||||||
start: start,
|
|
||||||
end: start,
|
|
||||||
});
|
|
||||||
next();
|
|
||||||
return arrow_function(start, [param]);
|
|
||||||
}
|
|
||||||
|
|
||||||
var left = maybe_conditional(no_in);
|
var left = maybe_conditional(no_in);
|
||||||
var val = S.token.value;
|
var val = S.token.value;
|
||||||
|
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ function mangle_properties(ast, options) {
|
|||||||
only_cache: false,
|
only_cache: false,
|
||||||
regex: null,
|
regex: null,
|
||||||
reserved: null,
|
reserved: null,
|
||||||
});
|
}, true);
|
||||||
|
|
||||||
var reserved = options.reserved;
|
var reserved = options.reserved;
|
||||||
if (!Array.isArray(reserved)) reserved = [];
|
if (!Array.isArray(reserved)) reserved = [];
|
||||||
|
|||||||
177
lib/scope.js
177
lib/scope.js
@@ -85,7 +85,7 @@ SymbolDef.prototype = {
|
|||||||
if (options.ie8 && sym instanceof AST_SymbolLambda)
|
if (options.ie8 && sym instanceof AST_SymbolLambda)
|
||||||
s = s.parent_scope;
|
s = s.parent_scope;
|
||||||
var def;
|
var def;
|
||||||
if (this.defun && (def = this.defun.variables.get(this.name))) {
|
if (def = this.redefined()) {
|
||||||
this.mangled_name = def.mangled_name || def.name;
|
this.mangled_name = def.mangled_name || def.name;
|
||||||
} else
|
} else
|
||||||
this.mangled_name = s.next_mangled(options, this);
|
this.mangled_name = s.next_mangled(options, this);
|
||||||
@@ -93,6 +93,9 @@ SymbolDef.prototype = {
|
|||||||
cache.set(this.name, this.mangled_name);
|
cache.set(this.name, this.mangled_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
redefined: function() {
|
||||||
|
return this.defun && this.defun.variables.get(this.name);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -129,7 +132,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
scope = save_scope;
|
scope = save_scope;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (node instanceof AST_Destructuring && node.is_array === false) {
|
if (node instanceof AST_Destructuring) {
|
||||||
in_destructuring = node; // These don't nest
|
in_destructuring = node; // These don't nest
|
||||||
descend();
|
descend();
|
||||||
in_destructuring = null;
|
in_destructuring = null;
|
||||||
@@ -223,10 +226,25 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
}));
|
}));
|
||||||
node.thedef = sym;
|
node.thedef = sym;
|
||||||
}
|
}
|
||||||
|
if (!(scope instanceof AST_Toplevel) && (node instanceof AST_Export || node instanceof AST_Import)) {
|
||||||
|
js_error(
|
||||||
|
node.TYPE + " statement may only appear at top level",
|
||||||
|
node.start.file,
|
||||||
|
node.start.line,
|
||||||
|
node.start.col,
|
||||||
|
node.start.pos
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function mark_export(def, level) {
|
function mark_export(def, level) {
|
||||||
|
if (in_destructuring) {
|
||||||
|
var i = 0;
|
||||||
|
do {
|
||||||
|
level++;
|
||||||
|
} while (tw.parent(i++) !== in_destructuring);
|
||||||
|
}
|
||||||
var node = tw.parent(level);
|
var node = tw.parent(level);
|
||||||
def.export = node instanceof AST_Export && !node.is_default;
|
def.export = node instanceof AST_Export;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
self.walk(tw);
|
self.walk(tw);
|
||||||
@@ -245,8 +263,9 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
s.uses_eval = true;
|
s.uses_eval = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var sym = node.scope.find_variable(name);
|
var sym;
|
||||||
if (!sym) {
|
if (tw.parent() instanceof AST_NameMapping && tw.parent(1).module_name
|
||||||
|
|| !(sym = node.scope.find_variable(name))) {
|
||||||
sym = self.def_global(node);
|
sym = self.def_global(node);
|
||||||
} else if (sym.scope instanceof AST_Lambda && name == "arguments") {
|
} else if (sym.scope instanceof AST_Lambda && name == "arguments") {
|
||||||
sym.scope.uses_arguments = true;
|
sym.scope.uses_arguments = true;
|
||||||
@@ -255,6 +274,16 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
node.reference(options);
|
node.reference(options);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
// ensure mangling works if catch reuses a scope variable
|
||||||
|
var def;
|
||||||
|
if (node instanceof AST_SymbolCatch && (def = node.definition().redefined())) {
|
||||||
|
var s = node.scope;
|
||||||
|
while (s) {
|
||||||
|
push_uniq(s.enclosed, def);
|
||||||
|
if (s === def.scope) break;
|
||||||
|
s = s.parent_scope;
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
self.walk(tw);
|
self.walk(tw);
|
||||||
|
|
||||||
@@ -421,7 +450,7 @@ AST_Function.DEFMETHOD("next_mangled", function(options, def){
|
|||||||
|
|
||||||
AST_Symbol.DEFMETHOD("unmangleable", function(options){
|
AST_Symbol.DEFMETHOD("unmangleable", function(options){
|
||||||
var def = this.definition();
|
var def = this.definition();
|
||||||
return def && def.unmangleable(options);
|
return !def || def.unmangleable(options);
|
||||||
});
|
});
|
||||||
|
|
||||||
// labels are always mangleable
|
// labels are always mangleable
|
||||||
@@ -432,14 +461,6 @@ AST_Symbol.DEFMETHOD("unreferenced", function(){
|
|||||||
&& !(this.scope.uses_eval || this.scope.uses_with);
|
&& !(this.scope.uses_eval || this.scope.uses_with);
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Symbol.DEFMETHOD("undeclared", function(){
|
|
||||||
return this.definition().undeclared;
|
|
||||||
});
|
|
||||||
|
|
||||||
AST_LabelRef.DEFMETHOD("undeclared", return_false);
|
|
||||||
|
|
||||||
AST_Label.DEFMETHOD("undeclared", return_false);
|
|
||||||
|
|
||||||
AST_Symbol.DEFMETHOD("definition", function(){
|
AST_Symbol.DEFMETHOD("definition", function(){
|
||||||
return this.thedef;
|
return this.thedef;
|
||||||
});
|
});
|
||||||
@@ -526,113 +547,69 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
|||||||
|
|
||||||
AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options){
|
AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options){
|
||||||
options = this._default_mangler_options(options);
|
options = this._default_mangler_options(options);
|
||||||
var tw = new TreeWalker(function(node){
|
try {
|
||||||
if (node instanceof AST_Constant)
|
AST_Node.prototype.print = function(stream, force_parens) {
|
||||||
base54.consider(node.print_to_string());
|
this._print(stream, force_parens);
|
||||||
else if (node instanceof AST_Return)
|
if (this instanceof AST_Symbol && !this.unmangleable(options)) {
|
||||||
base54.consider("return");
|
base54.consider(this.name, -1);
|
||||||
else if (node instanceof AST_Throw)
|
} else if (options.properties) {
|
||||||
base54.consider("throw");
|
if (this instanceof AST_Dot) {
|
||||||
else if (node instanceof AST_Continue)
|
base54.consider(this.property, -1);
|
||||||
base54.consider("continue");
|
} else if (this instanceof AST_Sub) {
|
||||||
else if (node instanceof AST_Break)
|
skip_string(this.property);
|
||||||
base54.consider("break");
|
}
|
||||||
else if (node instanceof AST_Debugger)
|
}
|
||||||
base54.consider("debugger");
|
};
|
||||||
else if (node instanceof AST_Directive)
|
base54.consider(this.print_to_string(), 1);
|
||||||
base54.consider(node.value);
|
} finally {
|
||||||
else if (node instanceof AST_While)
|
AST_Node.prototype.print = AST_Node.prototype._print;
|
||||||
base54.consider("while");
|
|
||||||
else if (node instanceof AST_Do)
|
|
||||||
base54.consider("do while");
|
|
||||||
else if (node instanceof AST_If) {
|
|
||||||
base54.consider("if");
|
|
||||||
if (node.alternative) base54.consider("else");
|
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_Var)
|
|
||||||
base54.consider("var");
|
|
||||||
else if (node instanceof AST_Const)
|
|
||||||
base54.consider("const");
|
|
||||||
else if (node instanceof AST_Lambda)
|
|
||||||
base54.consider("function");
|
|
||||||
else if (node instanceof AST_For)
|
|
||||||
base54.consider("for");
|
|
||||||
else if (node instanceof AST_ForIn)
|
|
||||||
base54.consider("for in");
|
|
||||||
else if (node instanceof AST_Switch)
|
|
||||||
base54.consider("switch");
|
|
||||||
else if (node instanceof AST_Case)
|
|
||||||
base54.consider("case");
|
|
||||||
else if (node instanceof AST_Default)
|
|
||||||
base54.consider("default");
|
|
||||||
else if (node instanceof AST_With)
|
|
||||||
base54.consider("with");
|
|
||||||
else if (node instanceof AST_ObjectSetter)
|
|
||||||
base54.consider("set" + (typeof node.key === "string" ? node.key : ""));
|
|
||||||
else if (node instanceof AST_ObjectGetter)
|
|
||||||
base54.consider("get" + (typeof node.key === "string" ? node.key : ""));
|
|
||||||
else if (node instanceof AST_ObjectKeyVal && typeof node.key === "string")
|
|
||||||
base54.consider(node.key);
|
|
||||||
else if (node instanceof AST_ConciseMethod && typeof node.key === "string")
|
|
||||||
base54.consider(node.key);
|
|
||||||
else if (node instanceof AST_New)
|
|
||||||
base54.consider("new");
|
|
||||||
else if (node instanceof AST_This)
|
|
||||||
base54.consider("this");
|
|
||||||
else if (node instanceof AST_Super)
|
|
||||||
base54.consider("super");
|
|
||||||
else if (node instanceof AST_Try)
|
|
||||||
base54.consider("try");
|
|
||||||
else if (node instanceof AST_Catch)
|
|
||||||
base54.consider("catch");
|
|
||||||
else if (node instanceof AST_Finally)
|
|
||||||
base54.consider("finally");
|
|
||||||
else if (node instanceof AST_Yield)
|
|
||||||
base54.consider("yield");
|
|
||||||
else if (node instanceof AST_Await)
|
|
||||||
base54.consider("await");
|
|
||||||
else if (node instanceof AST_Symbol && node.unmangleable(options))
|
|
||||||
base54.consider(node.name);
|
|
||||||
else if (node instanceof AST_Unary || node instanceof AST_Binary)
|
|
||||||
base54.consider(node.operator);
|
|
||||||
else if (node instanceof AST_Dot)
|
|
||||||
base54.consider(node.property);
|
|
||||||
});
|
|
||||||
this.walk(tw);
|
|
||||||
base54.sort();
|
base54.sort();
|
||||||
|
|
||||||
|
function skip_string(node) {
|
||||||
|
if (node instanceof AST_String) {
|
||||||
|
base54.consider(node.value, -1);
|
||||||
|
} else if (node instanceof AST_Conditional) {
|
||||||
|
skip_string(node.consequent);
|
||||||
|
skip_string(node.alternative);
|
||||||
|
} else if (node instanceof AST_Sequence) {
|
||||||
|
skip_string(node.expressions[node.expressions.length - 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var base54 = (function() {
|
var base54 = (function() {
|
||||||
var string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_0123456789";
|
var leading = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_".split("");
|
||||||
|
var digits = "0123456789".split("");
|
||||||
var chars, frequency;
|
var chars, frequency;
|
||||||
function reset() {
|
function reset() {
|
||||||
frequency = Object.create(null);
|
frequency = Object.create(null);
|
||||||
chars = string.split("").map(function(ch){ return ch.charCodeAt(0) });
|
leading.forEach(function(ch) {
|
||||||
chars.forEach(function(ch){ frequency[ch] = 0 });
|
frequency[ch] = 0;
|
||||||
|
});
|
||||||
|
digits.forEach(function(ch) {
|
||||||
|
frequency[ch] = 0;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
base54.consider = function(str){
|
base54.consider = function(str, delta) {
|
||||||
for (var i = str.length; --i >= 0;) {
|
for (var i = str.length; --i >= 0;) {
|
||||||
var code = str.charCodeAt(i);
|
frequency[str[i]] += delta;
|
||||||
if (code in frequency) ++frequency[code];
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
base54.sort = function() {
|
function compare(a, b) {
|
||||||
chars = mergeSort(chars, function(a, b){
|
|
||||||
if (is_digit(a) && !is_digit(b)) return 1;
|
|
||||||
if (is_digit(b) && !is_digit(a)) return -1;
|
|
||||||
return frequency[b] - frequency[a];
|
return frequency[b] - frequency[a];
|
||||||
});
|
}
|
||||||
|
base54.sort = function() {
|
||||||
|
chars = mergeSort(leading, compare).concat(mergeSort(digits, compare));
|
||||||
};
|
};
|
||||||
base54.reset = reset;
|
base54.reset = reset;
|
||||||
reset();
|
reset();
|
||||||
base54.get = function(){ return chars };
|
|
||||||
base54.freq = function(){ return frequency };
|
|
||||||
function base54(num) {
|
function base54(num) {
|
||||||
var ret = "", base = 54;
|
var ret = "", base = 54;
|
||||||
num++;
|
num++;
|
||||||
do {
|
do {
|
||||||
num--;
|
num--;
|
||||||
ret += String.fromCharCode(chars[num % base]);
|
ret += chars[num % base];
|
||||||
num = Math.floor(num / base);
|
num = Math.floor(num / base);
|
||||||
base = 64;
|
base = 64;
|
||||||
} while (num > 0);
|
} while (num > 0);
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ TreeTransformer.prototype = new TreeWalker;
|
|||||||
if (y !== undefined) x = y;
|
if (y !== undefined) x = y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tw.pop(this);
|
tw.pop();
|
||||||
return x;
|
return x;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -243,9 +243,22 @@ TreeTransformer.prototype = new TreeWalker;
|
|||||||
self.expression = self.expression.transform(tw);
|
self.expression = self.expression.transform(tw);
|
||||||
});
|
});
|
||||||
|
|
||||||
_(AST_Export, function(self, tw){
|
_(AST_NameMapping, function(self, tw) {
|
||||||
|
self.foreign_name = self.foreign_name.transform(tw);
|
||||||
|
self.name = self.name.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Import, function(self, tw) {
|
||||||
|
if (self.imported_name) self.imported_name = self.imported_name.transform(tw);
|
||||||
|
if (self.imported_names) do_list(self.imported_names, tw);
|
||||||
|
self.module_name = self.module_name.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Export, function(self, tw) {
|
||||||
if (self.exported_definition) self.exported_definition = self.exported_definition.transform(tw);
|
if (self.exported_definition) self.exported_definition = self.exported_definition.transform(tw);
|
||||||
if (self.exported_value) self.exported_value = self.exported_value.transform(tw);
|
if (self.exported_value) self.exported_value = self.exported_value.transform(tw);
|
||||||
|
if (self.exported_names) do_list(self.exported_names, tw);
|
||||||
|
if (self.module_name) self.module_name = self.module_name.transform(tw);
|
||||||
});
|
});
|
||||||
|
|
||||||
_(AST_TemplateString, function(self, tw) {
|
_(AST_TemplateString, function(self, tw) {
|
||||||
|
|||||||
28
package.json
28
package.json
@@ -1,20 +1,17 @@
|
|||||||
{
|
{
|
||||||
"name": "uglify-es",
|
"name": "uglify-es",
|
||||||
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
"description": "JavaScript parser, mangler/compressor and beautifier toolkit for ES6+",
|
||||||
"homepage": "https://github.com/mishoo/UglifyJS2/tree/harmony",
|
"homepage": "https://github.com/mishoo/UglifyJS2/tree/harmony",
|
||||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"version": "3.0.17",
|
"version": "3.0.25",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
},
|
},
|
||||||
"maintainers": [
|
"maintainers": [
|
||||||
"Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)"
|
"Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)"
|
||||||
],
|
],
|
||||||
"repository": {
|
"repository": "git+https://github.com/mishoo/UglifyJS2.git#harmony",
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/mishoo/UglifyJS2.git"
|
|
||||||
},
|
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/mishoo/UglifyJS2/issues"
|
"url": "https://github.com/mishoo/UglifyJS2/issues"
|
||||||
},
|
},
|
||||||
@@ -40,5 +37,22 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "node test/run-tests.js"
|
"test": "node test/run-tests.js"
|
||||||
},
|
},
|
||||||
"keywords": ["uglify", "uglify-js", "uglify-es", "minify", "minifier", "es5", "es6", "es2015"]
|
"keywords": [
|
||||||
|
"uglify",
|
||||||
|
"uglify-es",
|
||||||
|
"uglify-js",
|
||||||
|
"minify",
|
||||||
|
"minifier",
|
||||||
|
"javascript",
|
||||||
|
"ecmascript",
|
||||||
|
"es5",
|
||||||
|
"es6",
|
||||||
|
"es7",
|
||||||
|
"es8",
|
||||||
|
"es2015",
|
||||||
|
"es2016",
|
||||||
|
"es2017",
|
||||||
|
"async",
|
||||||
|
"await"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
var createHash = require("crypto").createHash;
|
var createHash = require("crypto").createHash;
|
||||||
var fetch = require("./fetch");
|
var fetch = require("./fetch");
|
||||||
var fork = require("child_process").fork;
|
var fork = require("child_process").fork;
|
||||||
|
var zlib = require("zlib");
|
||||||
var args = process.argv.slice(2);
|
var args = process.argv.slice(2);
|
||||||
if (!args.length) {
|
if (!args.length) {
|
||||||
args.push("-mc");
|
args.push("-mc");
|
||||||
@@ -33,6 +34,7 @@ function done() {
|
|||||||
console.log(info.log);
|
console.log(info.log);
|
||||||
console.log("Original:", info.input, "bytes");
|
console.log("Original:", info.input, "bytes");
|
||||||
console.log("Uglified:", info.output, "bytes");
|
console.log("Uglified:", info.output, "bytes");
|
||||||
|
console.log("GZipped: ", info.gzip, "bytes");
|
||||||
console.log("SHA1 sum:", info.sha1);
|
console.log("SHA1 sum:", info.sha1);
|
||||||
if (info.code) {
|
if (info.code) {
|
||||||
failures.push(url);
|
failures.push(url);
|
||||||
@@ -51,6 +53,7 @@ urls.forEach(function(url) {
|
|||||||
results[url] = {
|
results[url] = {
|
||||||
input: 0,
|
input: 0,
|
||||||
output: 0,
|
output: 0,
|
||||||
|
gzip: 0,
|
||||||
log: ""
|
log: ""
|
||||||
};
|
};
|
||||||
fetch(url, function(err, res) {
|
fetch(url, function(err, res) {
|
||||||
@@ -61,6 +64,10 @@ urls.forEach(function(url) {
|
|||||||
}).pipe(uglifyjs.stdin);
|
}).pipe(uglifyjs.stdin);
|
||||||
uglifyjs.stdout.on("data", function(data) {
|
uglifyjs.stdout.on("data", function(data) {
|
||||||
results[url].output += data.length;
|
results[url].output += data.length;
|
||||||
|
}).pipe(zlib.createGzip({
|
||||||
|
level: zlib.Z_BEST_COMPRESSION
|
||||||
|
})).on("data", function(data) {
|
||||||
|
results[url].gzip += data.length;
|
||||||
}).pipe(createHash("sha1")).on("data", function(data) {
|
}).pipe(createHash("sha1")).on("data", function(data) {
|
||||||
results[url].sha1 = data.toString("hex");
|
results[url].sha1 = data.toString("hex");
|
||||||
done();
|
done();
|
||||||
|
|||||||
@@ -202,3 +202,398 @@ arrow_unused_toplevel: {
|
|||||||
expect_stdout: [ "0", "1", "2", "9" ]
|
expect_stdout: [ "0", "1", "2", "9" ]
|
||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
no_leading_parentheses: {
|
||||||
|
input: {
|
||||||
|
(x,y) => x(y);
|
||||||
|
async (x,y) => await x(y);
|
||||||
|
}
|
||||||
|
expect_exact: "(x,y)=>x(y);async(x,y)=>await x(y);"
|
||||||
|
}
|
||||||
|
|
||||||
|
async_identifiers: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
ecma: 6,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var async = function(x){ console.log("async", x); };
|
||||||
|
var await = function(x){ console.log("await", x); };
|
||||||
|
async(1);
|
||||||
|
await(2);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var async = x => { console.log("async", x); };
|
||||||
|
var await = x => { console.log("await", x); };
|
||||||
|
async(1);
|
||||||
|
await(2);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"async 1",
|
||||||
|
"await 2",
|
||||||
|
]
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
async_function_expression: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
ecma: 6,
|
||||||
|
evaluate: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var named = async function foo() {
|
||||||
|
await bar(1 + 0) + (2 + 0);
|
||||||
|
}
|
||||||
|
var anon = async function() {
|
||||||
|
await (1 + 0) + bar(2 + 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var named = async function foo() {
|
||||||
|
await bar(1);
|
||||||
|
};
|
||||||
|
var anon = async () => {
|
||||||
|
await 1, bar(2);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_27: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
ecma: 6,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(jQuery) {
|
||||||
|
var $;
|
||||||
|
$ = jQuery;
|
||||||
|
$("body").addClass("foo");
|
||||||
|
})(jQuery);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(jQuery => {
|
||||||
|
jQuery("body").addClass("foo");
|
||||||
|
})(jQuery);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2105_1: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
ecma: 6,
|
||||||
|
inline: true,
|
||||||
|
passes: 3,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function(factory) {
|
||||||
|
factory();
|
||||||
|
}( function() {
|
||||||
|
return function(fn) {
|
||||||
|
fn()().prop();
|
||||||
|
}( function() {
|
||||||
|
function bar() {
|
||||||
|
var quux = function() {
|
||||||
|
console.log("PASS");
|
||||||
|
}, foo = function() {
|
||||||
|
console.log;
|
||||||
|
quux();
|
||||||
|
};
|
||||||
|
return { prop: foo };
|
||||||
|
}
|
||||||
|
return bar;
|
||||||
|
} );
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(() => {
|
||||||
|
var quux = () => {
|
||||||
|
console.log("PASS");
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
prop() {
|
||||||
|
console.log;
|
||||||
|
quux();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})().prop();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2105_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 2,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
((factory) => {
|
||||||
|
factory();
|
||||||
|
})( () => {
|
||||||
|
return ((fn) => {
|
||||||
|
fn()().prop();
|
||||||
|
})( () => {
|
||||||
|
let bar = () => {
|
||||||
|
var quux = () => {
|
||||||
|
console.log("PASS");
|
||||||
|
}, foo = () => {
|
||||||
|
console.log;
|
||||||
|
quux();
|
||||||
|
};
|
||||||
|
return { prop: foo };
|
||||||
|
};
|
||||||
|
return bar;
|
||||||
|
} );
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(() => {
|
||||||
|
var quux = () => {
|
||||||
|
console.log("PASS");
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
prop: () => {
|
||||||
|
console.log;
|
||||||
|
quux();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})().prop();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2136_2: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
ecma: 6,
|
||||||
|
inline: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(x) {
|
||||||
|
console.log(x);
|
||||||
|
}
|
||||||
|
!function(a, ...b) {
|
||||||
|
f(b[0]);
|
||||||
|
}(1, 2, 3);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(x) {
|
||||||
|
console.log(x);
|
||||||
|
}
|
||||||
|
f([2,3][0]);
|
||||||
|
}
|
||||||
|
expect_stdout: "2"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2136_3: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
ecma: 6,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 3,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unsafe: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(x) {
|
||||||
|
console.log(x);
|
||||||
|
}
|
||||||
|
!function(a, ...b) {
|
||||||
|
f(b[0]);
|
||||||
|
}(1, 2, 3);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(2);
|
||||||
|
}
|
||||||
|
expect_stdout: "2"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
call_args: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
ecma: 6,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
const a = 1;
|
||||||
|
console.log(a);
|
||||||
|
+function(a) {
|
||||||
|
return a;
|
||||||
|
}(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
const a = 1;
|
||||||
|
console.log(1);
|
||||||
|
+(1, 1);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
call_args_drop_param: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
ecma: 6,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
const a = 1;
|
||||||
|
console.log(a);
|
||||||
|
+function(a) {
|
||||||
|
return a;
|
||||||
|
}(a, b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
const a = 1;
|
||||||
|
console.log(1);
|
||||||
|
+(b, 1);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_485_crashing_1530: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
conditionals: true,
|
||||||
|
dead_code: true,
|
||||||
|
ecma: 6,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a) {
|
||||||
|
if (true) return;
|
||||||
|
var b = 42;
|
||||||
|
})(this);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
this, void 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2084: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
ecma: 6,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 2,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var c = 0;
|
||||||
|
!function() {
|
||||||
|
!function(c) {
|
||||||
|
c = 1 + c;
|
||||||
|
var c = 0;
|
||||||
|
function f14(a_1) {
|
||||||
|
if (c = 1 + c, 0 !== 23..toString())
|
||||||
|
c = 1 + c, a_1 && (a_1[0] = 0);
|
||||||
|
}
|
||||||
|
f14();
|
||||||
|
}(-1);
|
||||||
|
}();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c = 0;
|
||||||
|
((c) => {
|
||||||
|
c = 1 + c,
|
||||||
|
c = 1 + (c = 0),
|
||||||
|
0 !== 23..toString() && (c = 1 + c);
|
||||||
|
})(-1),
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: "0"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
export_default_object_expression: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
evaluate: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
export default {
|
||||||
|
foo: 1 + 2,
|
||||||
|
bar() { return 4; },
|
||||||
|
get baz() { return this.foo; },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
expect_exact: "export default{foo:3,bar:()=>4,get baz(){return this.foo}};"
|
||||||
|
}
|
||||||
|
|
||||||
|
concise_methods_with_computed_property2: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
evaluate: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var foo = {
|
||||||
|
[[1]](v) {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
console.log(foo[[1]]("PASS"));
|
||||||
|
}
|
||||||
|
expect_exact: 'var foo={[[1]]:v=>v};console.log(foo[[1]]("PASS"));'
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
async_object_literal: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
ecma: 6,
|
||||||
|
evaluate: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var obj = {
|
||||||
|
async a() {
|
||||||
|
return await foo(1 + 0);
|
||||||
|
},
|
||||||
|
anon: async function() {
|
||||||
|
return await foo(2 + 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var obj = {
|
||||||
|
a: async () => await foo(1),
|
||||||
|
anon: async () => await foo(2)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,6 +6,22 @@ await_precedence: {
|
|||||||
expect_exact: "async function f1(){await x+y}async function f2(){await(x+y)}"
|
expect_exact: "async function f1(){await x+y}async function f2(){await(x+y)}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await_precedence_prop: {
|
||||||
|
input: {
|
||||||
|
async function f1(){ return (await foo()).bar; }
|
||||||
|
async function f2(){ return (await foo().bar); }
|
||||||
|
}
|
||||||
|
expect_exact: "async function f1(){return(await foo()).bar}async function f2(){return await foo().bar}"
|
||||||
|
}
|
||||||
|
|
||||||
|
await_precedence_call: {
|
||||||
|
input: {
|
||||||
|
async function f3(){ return (await foo())(); }
|
||||||
|
async function f4(){ return await (foo()()); }
|
||||||
|
}
|
||||||
|
expect_exact: "async function f3(){return(await foo())()}async function f4(){return await foo()()}"
|
||||||
|
}
|
||||||
|
|
||||||
async_function_declaration: {
|
async_function_declaration: {
|
||||||
options = {
|
options = {
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
@@ -167,14 +183,14 @@ async_inline: {
|
|||||||
|
|
||||||
async_identifiers: {
|
async_identifiers: {
|
||||||
input: {
|
input: {
|
||||||
let async = function(x){ console.log("async", x); };
|
var async = function(x){ console.log("async", x); };
|
||||||
let await = function(x){ console.log("await", x); };
|
var await = function(x){ console.log("await", x); };
|
||||||
async(1);
|
async(1);
|
||||||
await(2);
|
await(2);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
let async = function(x){ console.log("async", x); };
|
var async = function(x){ console.log("async", x); };
|
||||||
let await = function(x){ console.log("await", x); };
|
var await = function(x){ console.log("await", x); };
|
||||||
async(1);
|
async(1);
|
||||||
await(2);
|
await(2);
|
||||||
}
|
}
|
||||||
@@ -182,19 +198,97 @@ async_identifiers: {
|
|||||||
"async 1",
|
"async 1",
|
||||||
"await 2",
|
"await 2",
|
||||||
]
|
]
|
||||||
node_version: ">=8"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: add test when supported by parser
|
async_shorthand_property: {
|
||||||
|
mangle = {
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function print(o) { console.log(o.async + " " + o.await); }
|
||||||
|
var async = "Async", await = "Await";
|
||||||
|
|
||||||
|
print({ async });
|
||||||
|
print({ await });
|
||||||
|
print({ async, await });
|
||||||
|
print({ await, async });
|
||||||
|
|
||||||
|
print({ async: async });
|
||||||
|
print({ await: await });
|
||||||
|
print({ async: async, await: await });
|
||||||
|
print({ await: await, async: async });
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function a(a) { console.log(a.async + " " + a.await); }
|
||||||
|
var n = "Async", c = "Await";
|
||||||
|
|
||||||
|
a({ async: n });
|
||||||
|
a({ await: c });
|
||||||
|
a({ async: n, await: c });
|
||||||
|
a({ await: c, async: n });
|
||||||
|
|
||||||
|
a({ async: n });
|
||||||
|
a({ await: c });
|
||||||
|
a({ async: n, await: c });
|
||||||
|
a({ await: c, async: n });
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"Async undefined",
|
||||||
|
"undefined Await",
|
||||||
|
"Async Await",
|
||||||
|
"Async Await",
|
||||||
|
"Async undefined",
|
||||||
|
"undefined Await",
|
||||||
|
"Async Await",
|
||||||
|
"Async Await",
|
||||||
|
]
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
async_arrow: {
|
async_arrow: {
|
||||||
input: {
|
input: {
|
||||||
let a1 = async x => await foo(x);
|
let a1 = async x => await foo(x);
|
||||||
let a2 = async () => await bar();
|
let a2 = async () => await bar();
|
||||||
let a3 = async (x) => await baz(x);
|
let a3 = async (x) => await baz(x);
|
||||||
let a4 = async (x, y) => { await far(x, y); }
|
let a4 = async (x, y) => { await far(x, y); }
|
||||||
let a5 = async ({x = [1], y: z = 2}) => { await wow(x, y); }
|
let a5 = async ({x = [1], y: z = 2}) => { await wow(x, z); }
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
|
let a1 = async x => await foo(x);
|
||||||
|
let a2 = async () => await bar();
|
||||||
|
let a3 = async (x) => await baz(x);
|
||||||
|
let a4 = async (x, y) => { await far(x, y); }
|
||||||
|
let a5 = async ({x = [1], y: z = 2}) => { await wow(x, z); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
async_arrow_wait: {
|
||||||
|
input: {
|
||||||
|
var a = async (x, y) => await x(y);
|
||||||
|
}
|
||||||
|
expect_exact: "var a=async(x,y)=>await x(y);"
|
||||||
|
}
|
||||||
|
|
||||||
|
async_arrow_iife: {
|
||||||
|
input: {
|
||||||
|
(async () => {
|
||||||
|
await fetch({});
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_exact: "(async()=>{await fetch({})})();"
|
||||||
|
}
|
||||||
|
|
||||||
|
async_arrow_iife_negate_iife: {
|
||||||
|
options = {
|
||||||
|
negate_iife: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(async () => {
|
||||||
|
await fetch();
|
||||||
|
})();
|
||||||
|
(() => {
|
||||||
|
plain();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_exact: "(async()=>{await fetch()})();(()=>{plain()})();"
|
||||||
|
}
|
||||||
|
|||||||
@@ -104,34 +104,36 @@ regression_block_scope_resolves: {
|
|||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
(function () {
|
(function () {
|
||||||
if(1) {
|
if (1) {
|
||||||
let x;
|
let x;
|
||||||
const y;
|
const y = 1;
|
||||||
class Zee {};
|
class Zee {};
|
||||||
}
|
}
|
||||||
if(1) {
|
if (1) {
|
||||||
let ex;
|
let ex;
|
||||||
const why;
|
const why = 2;
|
||||||
class Zi {};
|
class Zi {};
|
||||||
}
|
}
|
||||||
console.log(x, y, Zee, ex, why, Zi);
|
console.log(typeof x, typeof y, typeof Zee, typeof ex, typeof why, typeof Zi);
|
||||||
}());
|
}());
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
(function () {
|
(function () {
|
||||||
if (1) {
|
if (1) {
|
||||||
let o;
|
let e;
|
||||||
const n;
|
const o = 1;
|
||||||
class c {};
|
class t {};
|
||||||
}
|
}
|
||||||
if (1) {
|
if (1) {
|
||||||
let o;
|
let e;
|
||||||
const n;
|
const o = 2;
|
||||||
class c {};
|
class t {};
|
||||||
}
|
}
|
||||||
console.log(x, y, Zee, ex, why, Zi);
|
console.log(typeof x, typeof y, typeof Zee, typeof ex, typeof why, typeof Zi);
|
||||||
}());
|
}());
|
||||||
}
|
}
|
||||||
|
expect_stdout: "undefined undefined undefined undefined undefined undefined"
|
||||||
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_block_scope_mangler: {
|
switch_block_scope_mangler: {
|
||||||
@@ -153,25 +155,37 @@ switch_block_scope_mangler: {
|
|||||||
console.log(cat);
|
console.log(cat);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
fn(1);
|
||||||
|
fn(2);
|
||||||
|
fn(3);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var fn = function(o) {
|
var fn = function(e) {
|
||||||
switch (o) {
|
switch (e) {
|
||||||
case 1:
|
case 1:
|
||||||
let e = o + 1
|
let l = e + 1
|
||||||
let c = o + 4;
|
let o = e + 4;
|
||||||
console.log(e, c);
|
console.log(l, o);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
let l = o + 2;
|
let n = e + 2;
|
||||||
console.log(l);
|
console.log(n);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
let a = o + 3;
|
let c = e + 3;
|
||||||
console.log(a);
|
console.log(c);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
fn(1);
|
||||||
|
fn(2);
|
||||||
|
fn(3);
|
||||||
}
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"2 5",
|
||||||
|
"4",
|
||||||
|
"6",
|
||||||
|
]
|
||||||
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -863,7 +863,7 @@ collapse_vars_unary: {
|
|||||||
input: {
|
input: {
|
||||||
function f0(o, p) {
|
function f0(o, p) {
|
||||||
var x = o[p];
|
var x = o[p];
|
||||||
delete x;
|
return delete x;
|
||||||
}
|
}
|
||||||
function f1(n) {
|
function f1(n) {
|
||||||
var k = !!n;
|
var k = !!n;
|
||||||
@@ -893,7 +893,7 @@ collapse_vars_unary: {
|
|||||||
expect: {
|
expect: {
|
||||||
function f0(o, p) {
|
function f0(o, p) {
|
||||||
var x = o[p];
|
var x = o[p];
|
||||||
delete x;
|
return delete x;
|
||||||
}
|
}
|
||||||
function f1(n) {
|
function f1(n) {
|
||||||
return n > +!!n
|
return n > +!!n
|
||||||
@@ -2077,10 +2077,10 @@ chained_3: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log(function(a, b) {
|
console.log(function(a, b) {
|
||||||
var c = a, c = b;
|
var c = 1, c = b;
|
||||||
b++;
|
b++;
|
||||||
return c;
|
return c;
|
||||||
}(1, 2));
|
}(0, 2));
|
||||||
}
|
}
|
||||||
expect_stdout: "2"
|
expect_stdout: "2"
|
||||||
}
|
}
|
||||||
@@ -2330,3 +2330,221 @@ reassign_const_2: {
|
|||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2187_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 1;
|
||||||
|
!function(foo) {
|
||||||
|
foo();
|
||||||
|
var a = 2;
|
||||||
|
console.log(a);
|
||||||
|
}(function() {
|
||||||
|
console.log(a);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 1;
|
||||||
|
!function(foo) {
|
||||||
|
foo();
|
||||||
|
var a = 2;
|
||||||
|
console.log(a);
|
||||||
|
}(function() {
|
||||||
|
console.log(a);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2187_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var b = 1;
|
||||||
|
console.log(function(a) {
|
||||||
|
return a && ++b;
|
||||||
|
}(b--));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var b = 1;
|
||||||
|
console.log(function(a) {
|
||||||
|
return b-- && ++b;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2187_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var b = 1;
|
||||||
|
console.log(function(a) {
|
||||||
|
return a && ++b;
|
||||||
|
}(b--));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var b = 1;
|
||||||
|
console.log(b-- && ++b);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2203_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
a = "FAIL";
|
||||||
|
console.log({
|
||||||
|
a: "PASS",
|
||||||
|
b: function() {
|
||||||
|
return function(c) {
|
||||||
|
return c.a;
|
||||||
|
}((String, (Object, this)));
|
||||||
|
}
|
||||||
|
}.b());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
a = "FAIL";
|
||||||
|
console.log({
|
||||||
|
a: "PASS",
|
||||||
|
b: function() {
|
||||||
|
return function(c) {
|
||||||
|
return c.a;
|
||||||
|
}((String, (Object, this)));
|
||||||
|
}
|
||||||
|
}.b());
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2203_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
a = "PASS";
|
||||||
|
console.log({
|
||||||
|
a: "FAIL",
|
||||||
|
b: function() {
|
||||||
|
return function(c) {
|
||||||
|
return c.a;
|
||||||
|
}((String, (Object, function() {
|
||||||
|
return this;
|
||||||
|
}())));
|
||||||
|
}
|
||||||
|
}.b());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
a = "PASS";
|
||||||
|
console.log({
|
||||||
|
a: "FAIL",
|
||||||
|
b: function() {
|
||||||
|
return function(c) {
|
||||||
|
return (String, (Object, function() {
|
||||||
|
return this;
|
||||||
|
}())).a;
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
}.b());
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2203_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
a = "FAIL";
|
||||||
|
console.log({
|
||||||
|
a: "PASS",
|
||||||
|
b: function() {
|
||||||
|
return function(c) {
|
||||||
|
return c.a;
|
||||||
|
}((String, (Object, (() => this)())));
|
||||||
|
}
|
||||||
|
}.b());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
a = "FAIL";
|
||||||
|
console.log({
|
||||||
|
a: "PASS",
|
||||||
|
b: function() {
|
||||||
|
return function(c) {
|
||||||
|
return c.a;
|
||||||
|
}((String, (Object, (() => this)())));
|
||||||
|
}
|
||||||
|
}.b());
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2203_4: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
a = "FAIL";
|
||||||
|
console.log({
|
||||||
|
a: "PASS",
|
||||||
|
b: function() {
|
||||||
|
return (c => {
|
||||||
|
return c.a;
|
||||||
|
})((String, (Object, (() => this)())));
|
||||||
|
}
|
||||||
|
}.b());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
a = "FAIL";
|
||||||
|
console.log({
|
||||||
|
a: "PASS",
|
||||||
|
b: function() {
|
||||||
|
return (c => {
|
||||||
|
return (String, (Object, (() => this)())).a;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
}.b());
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
duplicate_argname: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() { return "PASS"; }
|
||||||
|
console.log(function(a, a) {
|
||||||
|
f++;
|
||||||
|
return a;
|
||||||
|
}("FAIL", f()));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() { return "PASS"; }
|
||||||
|
console.log(function(a, a) {
|
||||||
|
f++;
|
||||||
|
return a;
|
||||||
|
}("FAIL", f()));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -377,3 +377,82 @@ accessor: {
|
|||||||
}
|
}
|
||||||
expect: {}
|
expect: {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2233_1: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
side_effects: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
Array.isArray;
|
||||||
|
Boolean;
|
||||||
|
console.log;
|
||||||
|
Error.name;
|
||||||
|
Function.length;
|
||||||
|
Math.random;
|
||||||
|
Number.isNaN;
|
||||||
|
RegExp;
|
||||||
|
Object.defineProperty;
|
||||||
|
String.fromCharCode;
|
||||||
|
}
|
||||||
|
expect: {}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2233_2: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unsafe: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var RegExp;
|
||||||
|
Array.isArray;
|
||||||
|
RegExp;
|
||||||
|
UndeclaredGlobal;
|
||||||
|
function foo() {
|
||||||
|
var Number;
|
||||||
|
AnotherUndeclaredGlobal;
|
||||||
|
Math.sin;
|
||||||
|
Number.isNaN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var RegExp;
|
||||||
|
UndeclaredGlobal;
|
||||||
|
function foo() {
|
||||||
|
var Number;
|
||||||
|
AnotherUndeclaredGlobal;
|
||||||
|
Number.isNaN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2233_3: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unsafe: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var RegExp;
|
||||||
|
Array.isArray;
|
||||||
|
RegExp;
|
||||||
|
UndeclaredGlobal;
|
||||||
|
function foo() {
|
||||||
|
var Number;
|
||||||
|
AnotherUndeclaredGlobal;
|
||||||
|
Math.sin;
|
||||||
|
Number.isNaN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
UndeclaredGlobal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -425,8 +425,8 @@ mangle_destructuring_decl: {
|
|||||||
expect: {
|
expect: {
|
||||||
function test(t) {
|
function test(t) {
|
||||||
let e = t.a || { e: 7, n: 8 };
|
let e = t.a || { e: 7, n: 8 };
|
||||||
let {t: n, e: o, n: s, s: a = 9, o: c, r: l} = e;
|
let {t: n, e: o, n: s, s: l = 9, o: a, r: c} = e;
|
||||||
console.log(n, o, s, a, c, l);
|
console.log(n, o, s, l, a, c);
|
||||||
}
|
}
|
||||||
test({ a: { t: 1, e: 2, n: 3, s: 4, o: 5, r: 6 } });
|
test({ a: { t: 1, e: 2, n: 3, s: 4, o: 5, r: 6 } });
|
||||||
test({});
|
test({});
|
||||||
@@ -462,15 +462,15 @@ mangle_destructuring_assign_toplevel_true: {
|
|||||||
test({});
|
test({});
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function n(n) {
|
function e(e) {
|
||||||
let t, a, c;
|
let l, s, a;
|
||||||
let l = n.a || { e: 7, n: 8 };
|
let c = e.a || { e: 7, n: 8 };
|
||||||
({t: o, e, n: s, s: t = 9, o: a, r: c} = l);
|
({t: n, e: o, n: t, s: l = 9, o: s, r: a} = c);
|
||||||
console.log(o, e, s, t, a, c);
|
console.log(n, o, t, l, s, a);
|
||||||
}
|
}
|
||||||
let o, e, s;
|
let n, o, t;
|
||||||
n({ a: { t: 1, e: 2, n: 3, s: 4, o: 5, r: 6 } });
|
e({ a: { t: 1, e: 2, n: 3, s: 4, o: 5, r: 6 } });
|
||||||
n({});
|
e({});
|
||||||
}
|
}
|
||||||
expect_stdout: [
|
expect_stdout: [
|
||||||
"1 2 3 4 5 6",
|
"1 2 3 4 5 6",
|
||||||
@@ -504,10 +504,10 @@ mangle_destructuring_assign_toplevel_false: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function test(o) {
|
function test(o) {
|
||||||
let s, a, c;
|
let s, l, a;
|
||||||
let l = o.a || { e: 7, n: 8 };
|
let c = o.a || { e: 7, n: 8 };
|
||||||
({t, e, n, s = 9, o: a, r: c} = l);
|
({t, e, n, s = 9, o: l, r: a} = c);
|
||||||
console.log(t, e, n, s, a, c);
|
console.log(t, e, n, s, l, a);
|
||||||
}
|
}
|
||||||
let t, e, n;
|
let t, e, n;
|
||||||
test({ a: { t: 1, e: 2, n: 3, s: 4, o: 5, r: 6 } });
|
test({ a: { t: 1, e: 2, n: 3, s: 4, o: 5, r: 6 } });
|
||||||
@@ -588,8 +588,8 @@ arrow_func_with_destructuring_args: {
|
|||||||
})({bar: 5 - 0}, [, 6]);
|
})({bar: 5 - 0}, [, 6]);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
(({foo: o = 1, bar: n = 2}, [a = 3, b = 4]) => {
|
(({foo: o = 1, bar: a = 2}, [b = 3, l = 4]) => {
|
||||||
console.log(o, n, a, b);
|
console.log(o, a, b, l);
|
||||||
})({bar: 5}, [, 6]);
|
})({bar: 5}, [, 6]);
|
||||||
}
|
}
|
||||||
expect_stdout: "1 5 3 6"
|
expect_stdout: "1 5 3 6"
|
||||||
@@ -639,3 +639,23 @@ issue_2044_ecma_6_beautify: {
|
|||||||
}
|
}
|
||||||
expect_exact: "({x: a = 1, y = 2 + b, z = 3 - c} = obj);"
|
expect_exact: "({x: a = 1, y = 2 + b, z = 3 - c} = obj);"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2140: {
|
||||||
|
options = {
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function() {
|
||||||
|
var t = {};
|
||||||
|
console.log(([t.a] = [42])[0]);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function() {
|
||||||
|
var t = {};
|
||||||
|
console.log(([t.a] = [42])[0]);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1210,6 +1210,7 @@ var_catch_toplevel: {
|
|||||||
a--;
|
a--;
|
||||||
try {
|
try {
|
||||||
a++;
|
a++;
|
||||||
|
x();
|
||||||
} catch(a) {
|
} catch(a) {
|
||||||
if (a) var a;
|
if (a) var a;
|
||||||
var a = 10;
|
var a = 10;
|
||||||
@@ -1219,9 +1220,8 @@ var_catch_toplevel: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
!function() {
|
!function() {
|
||||||
a--;
|
|
||||||
try {
|
try {
|
||||||
a++;
|
x();
|
||||||
} catch(a) {
|
} catch(a) {
|
||||||
var a;
|
var a;
|
||||||
}
|
}
|
||||||
@@ -1294,3 +1294,222 @@ issue_2063: {
|
|||||||
var a;
|
var a;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2105: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 3,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function(factory) {
|
||||||
|
factory();
|
||||||
|
}( function() {
|
||||||
|
return function(fn) {
|
||||||
|
fn()().prop();
|
||||||
|
}( function() {
|
||||||
|
function bar() {
|
||||||
|
var quux = function() {
|
||||||
|
console.log("PASS");
|
||||||
|
}, foo = function() {
|
||||||
|
console.log;
|
||||||
|
quux();
|
||||||
|
};
|
||||||
|
return { prop: foo };
|
||||||
|
}
|
||||||
|
return bar;
|
||||||
|
} );
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
var quux = function() {
|
||||||
|
console.log("PASS");
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
prop: function() {
|
||||||
|
console.log;
|
||||||
|
quux();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})().prop();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2136_1: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function(a, ...b) {
|
||||||
|
console.log(b);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function(a, ...b) {
|
||||||
|
console.log(b);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: "[]"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2136_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(x) {
|
||||||
|
console.log(x);
|
||||||
|
}
|
||||||
|
!function(a, ...b) {
|
||||||
|
f(b[0]);
|
||||||
|
}(1, 2, 3);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(x) {
|
||||||
|
console.log(x);
|
||||||
|
}
|
||||||
|
f([2,3][0]);
|
||||||
|
}
|
||||||
|
expect_stdout: "2"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2136_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 3,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unsafe: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(x) {
|
||||||
|
console.log(x);
|
||||||
|
}
|
||||||
|
!function(a, ...b) {
|
||||||
|
f(b[0]);
|
||||||
|
}(1, 2, 3);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(2);
|
||||||
|
}
|
||||||
|
expect_stdout: "2"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2163: {
|
||||||
|
options = {
|
||||||
|
pure_funcs: [ "pure" ],
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var c;
|
||||||
|
/*@__PURE__*/f(...a);
|
||||||
|
pure(b, ...c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c;
|
||||||
|
a;
|
||||||
|
b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2226_1: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f1() {
|
||||||
|
var a = b;
|
||||||
|
a += c;
|
||||||
|
}
|
||||||
|
function f2(a) {
|
||||||
|
a <<= b;
|
||||||
|
}
|
||||||
|
function f3(a) {
|
||||||
|
--a;
|
||||||
|
}
|
||||||
|
function f4() {
|
||||||
|
var a = b;
|
||||||
|
return a *= c;
|
||||||
|
}
|
||||||
|
function f5(a) {
|
||||||
|
x(a /= b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f1() {
|
||||||
|
b;
|
||||||
|
c;
|
||||||
|
}
|
||||||
|
function f2(a) {
|
||||||
|
b;
|
||||||
|
}
|
||||||
|
function f3(a) {
|
||||||
|
0;
|
||||||
|
}
|
||||||
|
function f4() {
|
||||||
|
var a = b;
|
||||||
|
return a *= c;
|
||||||
|
}
|
||||||
|
function f5(a) {
|
||||||
|
x(a /= b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2226_2: {
|
||||||
|
options = {
|
||||||
|
cascade: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a, b) {
|
||||||
|
a += b;
|
||||||
|
return a;
|
||||||
|
}(1, 2));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a, b) {
|
||||||
|
return a += b;
|
||||||
|
}(1, 2));
|
||||||
|
}
|
||||||
|
expect_stdout: "3"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2226_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a, b) {
|
||||||
|
a += b;
|
||||||
|
return a;
|
||||||
|
}(1, 2));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a, b) {
|
||||||
|
return a += 2;
|
||||||
|
}(1));
|
||||||
|
}
|
||||||
|
expect_stdout: "3"
|
||||||
|
}
|
||||||
|
|||||||
@@ -344,22 +344,26 @@ unsafe_constant: {
|
|||||||
|
|
||||||
unsafe_object: {
|
unsafe_object: {
|
||||||
options = {
|
options = {
|
||||||
evaluate : true,
|
evaluate: true,
|
||||||
unsafe : true
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unsafe: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
var o = { a: 1 };
|
||||||
console.log(
|
console.log(
|
||||||
({a:1}) + 1,
|
o + 1,
|
||||||
({a:1}).a + 1,
|
o.a + 1,
|
||||||
({a:1}).b + 1,
|
o.b + 1,
|
||||||
({a:1}).a.b + 1
|
o.a.b + 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
|
var o = { a: 1 };
|
||||||
console.log(
|
console.log(
|
||||||
({a:1}) + 1,
|
o + 1,
|
||||||
2,
|
2,
|
||||||
({a:1}).b + 1,
|
o.b + 1,
|
||||||
1..b + 1
|
1..b + 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -368,22 +372,26 @@ unsafe_object: {
|
|||||||
|
|
||||||
unsafe_object_nested: {
|
unsafe_object_nested: {
|
||||||
options = {
|
options = {
|
||||||
evaluate : true,
|
evaluate: true,
|
||||||
unsafe : true
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unsafe: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
var o = { a: { b: 1 } };
|
||||||
console.log(
|
console.log(
|
||||||
({a:{b:1}}) + 1,
|
o + 1,
|
||||||
({a:{b:1}}).a + 1,
|
o.a + 1,
|
||||||
({a:{b:1}}).b + 1,
|
o.b + 1,
|
||||||
({a:{b:1}}).a.b + 1
|
o.a.b + 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
|
var o = { a: { b: 1 } };
|
||||||
console.log(
|
console.log(
|
||||||
({a:{b:1}}) + 1,
|
o + 1,
|
||||||
({a:{b:1}}).a + 1,
|
o.a + 1,
|
||||||
({a:{b:1}}).b + 1,
|
o.b + 1,
|
||||||
2
|
2
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -392,21 +400,25 @@ unsafe_object_nested: {
|
|||||||
|
|
||||||
unsafe_object_complex: {
|
unsafe_object_complex: {
|
||||||
options = {
|
options = {
|
||||||
evaluate : true,
|
evaluate: true,
|
||||||
unsafe : true
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unsafe: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
var o = { a: { b: 1 }, b: 1 };
|
||||||
console.log(
|
console.log(
|
||||||
({a:{b:1},b:1}) + 1,
|
o + 1,
|
||||||
({a:{b:1},b:1}).a + 1,
|
o.a + 1,
|
||||||
({a:{b:1},b:1}).b + 1,
|
o.b + 1,
|
||||||
({a:{b:1},b:1}).a.b + 1
|
o.a.b + 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
|
var o = { a: { b: 1 }, b: 1 };
|
||||||
console.log(
|
console.log(
|
||||||
({a:{b:1},b:1}) + 1,
|
o + 1,
|
||||||
({a:{b:1},b:1}).a + 1,
|
o.a + 1,
|
||||||
2,
|
2,
|
||||||
2
|
2
|
||||||
);
|
);
|
||||||
@@ -416,22 +428,26 @@ unsafe_object_complex: {
|
|||||||
|
|
||||||
unsafe_object_repeated: {
|
unsafe_object_repeated: {
|
||||||
options = {
|
options = {
|
||||||
evaluate : true,
|
evaluate: true,
|
||||||
unsafe : true
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unsafe: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
var o = { a: { b: 1 }, a: 1 };
|
||||||
console.log(
|
console.log(
|
||||||
({a:{b:1},a:1}) + 1,
|
o + 1,
|
||||||
({a:{b:1},a:1}).a + 1,
|
o.a + 1,
|
||||||
({a:{b:1},a:1}).b + 1,
|
o.b + 1,
|
||||||
({a:{b:1},a:1}).a.b + 1
|
o.a.b + 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
|
var o = { a: { b: 1 }, a: 1 };
|
||||||
console.log(
|
console.log(
|
||||||
({a:{b:1},a:1}) + 1,
|
o + 1,
|
||||||
2,
|
2,
|
||||||
({a:{b:1},a:1}).b + 1,
|
o.b + 1,
|
||||||
1..b + 1
|
1..b + 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -480,9 +496,9 @@ unsafe_function: {
|
|||||||
expect: {
|
expect: {
|
||||||
console.log(
|
console.log(
|
||||||
({a:{b:1},b:function(){}}) + 1,
|
({a:{b:1},b:function(){}}) + 1,
|
||||||
({a:{b:1},b:function(){}}).a + 1,
|
({b:function(){}}, {b:1}) + 1,
|
||||||
({a:{b:1},b:function(){}}).b + 1,
|
({a:{b:1}}, function(){}) + 1,
|
||||||
({a:{b:1},b:function(){}}).a.b + 1
|
({b:function(){}}, {b:1}).b + 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
@@ -730,8 +746,8 @@ unsafe_prototype_function: {
|
|||||||
var d = ({toString: 0}) + "";
|
var d = ({toString: 0}) + "";
|
||||||
var e = (({valueOf: 0}) + "")[2];
|
var e = (({valueOf: 0}) + "")[2];
|
||||||
var f = (({toString: 0}) + "")[2];
|
var f = (({toString: 0}) + "")[2];
|
||||||
var g = ({valueOf: 0}).valueOf();
|
var g = ({}, 0)();
|
||||||
var h = "" + ({toString: 0});
|
var h = ({}, 0)();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1162,3 +1178,103 @@ string_charCodeAt: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "NaN"
|
expect_stdout: "NaN"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2207_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(String.fromCharCode(65));
|
||||||
|
console.log(Math.max(3, 6, 2, 7, 3, 4));
|
||||||
|
console.log(Math.cos(1.2345));
|
||||||
|
console.log(Math.cos(1.2345) - Math.sin(4.321));
|
||||||
|
console.log(Math.pow(Math.PI, Math.E - Math.LN10));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("A");
|
||||||
|
console.log(7);
|
||||||
|
console.log(Math.cos(1.2345));
|
||||||
|
console.log(1.2543732512566947);
|
||||||
|
console.log(1.6093984514472044);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2207_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(Math.E);
|
||||||
|
console.log(Math.LN10);
|
||||||
|
console.log(Math.LN2);
|
||||||
|
console.log(Math.LOG2E);
|
||||||
|
console.log(Math.LOG10E);
|
||||||
|
console.log(Math.PI);
|
||||||
|
console.log(Math.SQRT1_2);
|
||||||
|
console.log(Math.SQRT2);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(Math.E);
|
||||||
|
console.log(Math.LN10);
|
||||||
|
console.log(Math.LN2);
|
||||||
|
console.log(Math.LOG2E);
|
||||||
|
console.log(Math.LOG10E);
|
||||||
|
console.log(Math.PI);
|
||||||
|
console.log(Math.SQRT1_2);
|
||||||
|
console.log(Math.SQRT2);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2207_3: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(Number.MAX_VALUE);
|
||||||
|
console.log(Number.MIN_VALUE);
|
||||||
|
console.log(Number.NaN);
|
||||||
|
console.log(Number.NEGATIVE_INFINITY);
|
||||||
|
console.log(Number.POSITIVE_INFINITY);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(Number.MAX_VALUE);
|
||||||
|
console.log(5e-324);
|
||||||
|
console.log(NaN);
|
||||||
|
console.log(-1/0);
|
||||||
|
console.log(1/0);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2231_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(Object.keys(void 0));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(Object.keys(void 0));
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2231_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(Object.getOwnPropertyNames(null));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(Object.getOwnPropertyNames(null));
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|||||||
228
test/compress/export.js
Normal file
228
test/compress/export.js
Normal file
@@ -0,0 +1,228 @@
|
|||||||
|
issue_2038_1: {
|
||||||
|
options = {
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
export var V = 1;
|
||||||
|
export let L = 2;
|
||||||
|
export const C = 3;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
export var V = 1;
|
||||||
|
export let L = 2;
|
||||||
|
export const C = 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2038_2: {
|
||||||
|
options = {
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
let LET = 1;
|
||||||
|
const CONST = 2;
|
||||||
|
var VAR = 3;
|
||||||
|
export { LET, CONST, VAR };
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
let t = 1;
|
||||||
|
const e = 2;
|
||||||
|
var o = 3;
|
||||||
|
export { t as LET, e as CONST, o as VAR };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2126: {
|
||||||
|
mangle = {
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
import { foo as bar, cat as dog } from "stuff";
|
||||||
|
console.log(bar, dog);
|
||||||
|
export { bar as qux };
|
||||||
|
export { dog };
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
import { foo as o, cat as s } from "stuff";
|
||||||
|
console.log(o, s);
|
||||||
|
export { o as qux };
|
||||||
|
export { s as dog };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
beautify: {
|
||||||
|
beautify = {
|
||||||
|
beautify: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
export { A as B, C as D };
|
||||||
|
}
|
||||||
|
expect_exact: "export { A as B, C as D };"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2131: {
|
||||||
|
options = {
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function no() {
|
||||||
|
console.log(42);
|
||||||
|
}
|
||||||
|
function go() {
|
||||||
|
console.log(42);
|
||||||
|
}
|
||||||
|
var X = 1, Y = 2;
|
||||||
|
export function main() {
|
||||||
|
go(X);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function go() {
|
||||||
|
console.log(42);
|
||||||
|
}
|
||||||
|
var X = 1;
|
||||||
|
export function main() {
|
||||||
|
go(X);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2129: {
|
||||||
|
mangle = {
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
export const { keys } = Object;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
export const { keys } = Object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async_func: {
|
||||||
|
options = {
|
||||||
|
keep_fargs: false,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
export async function Foo(x){};
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
export async function Foo(){};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2134_1: {
|
||||||
|
options = {
|
||||||
|
keep_fargs: false,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
export function Foo(x){};
|
||||||
|
Foo.prototype = {};
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
export function Foo(){};
|
||||||
|
Foo.prototype = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2134_2: {
|
||||||
|
options = {
|
||||||
|
keep_fargs: false,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
export async function Foo(x){};
|
||||||
|
Foo.prototype = {};
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
export async function Foo(){};
|
||||||
|
Foo.prototype = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
redirection: {
|
||||||
|
mangle = {
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
let foo = 1, bar = 2;
|
||||||
|
export { foo as delete };
|
||||||
|
export { bar as default };
|
||||||
|
export { foo as var } from "module.js";
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
let e = 1, o = 2;
|
||||||
|
export { e as delete };
|
||||||
|
export { o as default };
|
||||||
|
export { foo as var } from "module.js";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
keyword_invalid_1: {
|
||||||
|
input: {
|
||||||
|
export { default };
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
export { default };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
keyword_invalid_2: {
|
||||||
|
input: {
|
||||||
|
export { default as Alias };
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
export { default as Alias };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
keyword_invalid_3: {
|
||||||
|
input: {
|
||||||
|
export { default as default };
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
export { default as default };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
keyword_valid_1: {
|
||||||
|
input: {
|
||||||
|
export { default } from "module.js";
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
export { default } from "module.js";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
keyword_valid_2: {
|
||||||
|
input: {
|
||||||
|
export { default as Alias } from "module.js";
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
export { default as Alias } from "module.js";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
keyword_valid_3: {
|
||||||
|
input: {
|
||||||
|
export { default as default } from "module.js";
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
export { default as default } from "module.js";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -265,7 +265,7 @@ issue_203: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var m = {};
|
var m = {};
|
||||||
var fn = Function("a", "b", "b.exports=42");
|
var fn = Function("n,o", "o.exports=42");
|
||||||
fn(null, m, m.exports);
|
fn(null, m, m.exports);
|
||||||
console.log(m.exports);
|
console.log(m.exports);
|
||||||
}
|
}
|
||||||
@@ -414,3 +414,97 @@ inner_ref: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "1 undefined"
|
expect_stdout: "1 undefined"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2107: {
|
||||||
|
options = {
|
||||||
|
cascade: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var c = 0;
|
||||||
|
!function() {
|
||||||
|
c++;
|
||||||
|
}(c++ + new function() {
|
||||||
|
this.a = 0;
|
||||||
|
var a = (c = c + 1) + (c = 1 + c);
|
||||||
|
return c++ + a;
|
||||||
|
}());
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c = 0;
|
||||||
|
c++, new function() {
|
||||||
|
this.a = 0, c = 1 + (c += 1), c++;
|
||||||
|
}(), c++, console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: "5"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2114_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
if_return: true,
|
||||||
|
inline: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var c = 0;
|
||||||
|
!function(a) {
|
||||||
|
a = 0;
|
||||||
|
}([ {
|
||||||
|
0: c = c + 1,
|
||||||
|
length: c = 1 + c
|
||||||
|
}, typeof void function a() {
|
||||||
|
var b = function f1(a) {
|
||||||
|
}(b && (b.b += (c = c + 1, 0)));
|
||||||
|
}() ]);
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c = 0;
|
||||||
|
c = 1 + (c += 1), function() {
|
||||||
|
var b = void (b && (b.b += (c += 1, 0)));
|
||||||
|
}();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: "2"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2114_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
if_return: true,
|
||||||
|
inline: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
passes: 2,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var c = 0;
|
||||||
|
!function(a) {
|
||||||
|
a = 0;
|
||||||
|
}([ {
|
||||||
|
0: c = c + 1,
|
||||||
|
length: c = 1 + c
|
||||||
|
}, typeof void function a() {
|
||||||
|
var b = function f1(a) {
|
||||||
|
}(b && (b.b += (c = c + 1, 0)));
|
||||||
|
}() ]);
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c = 0;
|
||||||
|
c = 1 + (c += 1), function() {
|
||||||
|
var b = void (b && (b.b += (c += 1, 0)));
|
||||||
|
}();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: "2"
|
||||||
|
}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ object: {
|
|||||||
VALUE: 42,
|
VALUE: 42,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
side_effects: true,
|
||||||
unsafe: true,
|
unsafe: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -140,9 +141,9 @@ mixed: {
|
|||||||
console.log(CONFIG);
|
console.log(CONFIG);
|
||||||
}
|
}
|
||||||
expect_warnings: [
|
expect_warnings: [
|
||||||
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:126,22]',
|
|
||||||
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:127,22]',
|
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:127,22]',
|
||||||
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:129,8]',
|
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:128,22]',
|
||||||
|
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:130,8]',
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,3 +175,24 @@ issue_1986: {
|
|||||||
console.log(42);
|
console.log(42);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2167: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
global_defs: {
|
||||||
|
"@isDevMode": "function(){}",
|
||||||
|
},
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
if (isDevMode()) {
|
||||||
|
greetOverlord();
|
||||||
|
}
|
||||||
|
doWork();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
doWork();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,9 +16,12 @@ typeof_arrow_functions: {
|
|||||||
evaluate: true
|
evaluate: true
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var foo = typeof (x) => null;
|
var foo = typeof (x => null);
|
||||||
|
console.log(foo);
|
||||||
}
|
}
|
||||||
expect_exact: "var foo=\"function\";"
|
expect_exact: "var foo=\"function\";console.log(foo);"
|
||||||
|
expect_stdout: "function"
|
||||||
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
classes: {
|
classes: {
|
||||||
@@ -60,15 +63,15 @@ class_name_can_be_mangled: {
|
|||||||
function x() {
|
function x() {
|
||||||
class Foo {
|
class Foo {
|
||||||
}
|
}
|
||||||
var class1 = Foo
|
var class1 = Foo;
|
||||||
var class2 = class Bar {}
|
var class2 = class Bar {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function x() {
|
function x() {
|
||||||
class a { }
|
class a { }
|
||||||
var n = a
|
var s = a;
|
||||||
var r = class a {}
|
var c = class a {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -287,12 +290,12 @@ import_statement_mangling: {
|
|||||||
Whatever();
|
Whatever();
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
import l from "foo";
|
import o from "foo";
|
||||||
import e, {Food as o} from "lel";
|
import m, {Food as r} from "lel";
|
||||||
import {What as f} from "lel";
|
import {What as f} from "lel";
|
||||||
l();
|
|
||||||
e();
|
|
||||||
o();
|
o();
|
||||||
|
m();
|
||||||
|
r();
|
||||||
f();
|
f();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -466,10 +469,10 @@ issue_1898: {
|
|||||||
expect: {
|
expect: {
|
||||||
class Foo {
|
class Foo {
|
||||||
bar() {
|
bar() {
|
||||||
for (const n of [ 6, 5 ])
|
for (const f of [ 6, 5 ])
|
||||||
for (let r of [ 4, 3 ])
|
for (let r of [ 4, 3 ])
|
||||||
for (var o of [ 2, 1 ])
|
for (var o of [ 2, 1 ])
|
||||||
console.log(n, r, o);
|
console.log(f, r, o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
new Foo().bar();
|
new Foo().bar();
|
||||||
@@ -494,9 +497,9 @@ issue_1753: {
|
|||||||
expect: {
|
expect: {
|
||||||
class SomeClass {
|
class SomeClass {
|
||||||
constructor(r) {
|
constructor(r) {
|
||||||
let a = [];
|
let s = [];
|
||||||
for (let s = 0; s < 6; s++)
|
for (let a = 0; a < 6; a++)
|
||||||
a.push({
|
s.push({
|
||||||
mainDrawNumbers: [],
|
mainDrawNumbers: [],
|
||||||
extraDrawNumbers: []
|
extraDrawNumbers: []
|
||||||
});
|
});
|
||||||
@@ -523,9 +526,9 @@ issue_1753_disable: {
|
|||||||
expect: {
|
expect: {
|
||||||
class SomeClass {
|
class SomeClass {
|
||||||
constructor(r) {
|
constructor(r) {
|
||||||
let a = [];
|
let s = [];
|
||||||
for (let r = 0; r < 6; r++)
|
for (let r = 0; r < 6; r++)
|
||||||
a.push({
|
s.push({
|
||||||
mainDrawNumbers: [],
|
mainDrawNumbers: [],
|
||||||
extraDrawNumbers: []
|
extraDrawNumbers: []
|
||||||
});
|
});
|
||||||
@@ -664,3 +667,31 @@ class_expression_statement_unused_toplevel: {
|
|||||||
}
|
}
|
||||||
expect_exact: ""
|
expect_exact: ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export_default_function_decl: {
|
||||||
|
options = {
|
||||||
|
toplevel: true,
|
||||||
|
passes: 3,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
// do not drop "unused" exports
|
||||||
|
export default function Foo() {};
|
||||||
|
export function Far() {};
|
||||||
|
}
|
||||||
|
expect_exact: "export default function Foo(){};export function Far(){};"
|
||||||
|
}
|
||||||
|
|
||||||
|
export_default_class_decl: {
|
||||||
|
options = {
|
||||||
|
toplevel: true,
|
||||||
|
passes: 3,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
// do not drop "unused" exports
|
||||||
|
export default class Car {};
|
||||||
|
export class Cab {};
|
||||||
|
}
|
||||||
|
expect_exact: "export default class Car{};export class Cab{};"
|
||||||
|
}
|
||||||
|
|||||||
@@ -71,11 +71,13 @@ non_hoisted_function_after_return_2a: {
|
|||||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:51,16]",
|
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:51,16]",
|
||||||
"WARN: Dropping unused variable a [test/compress/issue-1034.js:48,20]",
|
"WARN: Dropping unused variable a [test/compress/issue-1034.js:48,20]",
|
||||||
"WARN: Dropping unused function nope [test/compress/issue-1034.js:55,21]",
|
"WARN: Dropping unused function nope [test/compress/issue-1034.js:55,21]",
|
||||||
|
"WARN: pass 0: last_count: Infinity, count: 37",
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:53,12]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:53,12]",
|
||||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:53,12]",
|
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:53,12]",
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:56,12]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:56,12]",
|
||||||
"WARN: Dropping unused variable b [test/compress/issue-1034.js:51,20]",
|
"WARN: Dropping unused variable b [test/compress/issue-1034.js:51,20]",
|
||||||
"WARN: Dropping unused variable c [test/compress/issue-1034.js:53,16]",
|
"WARN: Dropping unused variable c [test/compress/issue-1034.js:53,16]",
|
||||||
|
"WARN: pass 1: last_count: 37, count: 18",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,11 +111,11 @@ non_hoisted_function_after_return_2b: {
|
|||||||
}
|
}
|
||||||
expect_warnings: [
|
expect_warnings: [
|
||||||
// duplicate warnings no longer emitted
|
// duplicate warnings no longer emitted
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:95,16]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:97,16]",
|
||||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:95,16]",
|
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:97,16]",
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:97,12]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:99,12]",
|
||||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:97,12]",
|
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:99,12]",
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:101,12]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:103,12]",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,10 +153,10 @@ non_hoisted_function_after_return_strict: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "8 7"
|
expect_stdout: "8 7"
|
||||||
expect_warnings: [
|
expect_warnings: [
|
||||||
'WARN: Dropping unreachable code [test/compress/issue-1034.js:131,16]',
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:133,16]",
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:134,16]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:136,16]",
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:137,12]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:139,12]",
|
||||||
"WARN: Dropping unused function UnusedFunction [test/compress/issue-1034.js:138,21]"
|
"WARN: Dropping unused function UnusedFunction [test/compress/issue-1034.js:140,21]",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,17 +196,19 @@ non_hoisted_function_after_return_2a_strict: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "5 6"
|
expect_stdout: "5 6"
|
||||||
expect_warnings: [
|
expect_warnings: [
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:173,16]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:175,16]",
|
||||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:173,16]",
|
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:175,16]",
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:176,16]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:178,16]",
|
||||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:176,16]",
|
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:178,16]",
|
||||||
"WARN: Dropping unused variable a [test/compress/issue-1034.js:173,20]",
|
"WARN: Dropping unused variable a [test/compress/issue-1034.js:175,20]",
|
||||||
"WARN: Dropping unused function nope [test/compress/issue-1034.js:180,21]",
|
"WARN: Dropping unused function nope [test/compress/issue-1034.js:182,21]",
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:178,12]",
|
"WARN: pass 0: last_count: Infinity, count: 48",
|
||||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:178,12]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:180,12]",
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:181,12]",
|
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:180,12]",
|
||||||
"WARN: Dropping unused variable b [test/compress/issue-1034.js:176,20]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:183,12]",
|
||||||
"WARN: Dropping unused variable c [test/compress/issue-1034.js:178,16]",
|
"WARN: Dropping unused variable b [test/compress/issue-1034.js:178,20]",
|
||||||
|
"WARN: Dropping unused variable c [test/compress/issue-1034.js:180,16]",
|
||||||
|
"WARN: pass 1: last_count: 48, count: 29",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,10 +247,10 @@ non_hoisted_function_after_return_2b_strict: {
|
|||||||
expect_stdout: "5 6"
|
expect_stdout: "5 6"
|
||||||
expect_warnings: [
|
expect_warnings: [
|
||||||
// duplicate warnings no longer emitted
|
// duplicate warnings no longer emitted
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:225,16]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:229,16]",
|
||||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:225,16]",
|
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:229,16]",
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:227,12]",
|
|
||||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:227,12]",
|
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:231,12]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:231,12]",
|
||||||
|
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:231,12]",
|
||||||
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:235,12]",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,9 +10,9 @@ issue_1321_no_debug: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var x = {};
|
var x = {};
|
||||||
x.b = 1;
|
x.o = 1;
|
||||||
x["a"] = 2 * x.b;
|
x["a"] = 2 * x.o;
|
||||||
console.log(x.b, x["a"]);
|
console.log(x.o, x["a"]);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
@@ -30,9 +30,9 @@ issue_1321_debug: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var x = {};
|
var x = {};
|
||||||
x.a = 1;
|
x.o = 1;
|
||||||
x["_$foo$_"] = 2 * x.a;
|
x["_$foo$_"] = 2 * x.o;
|
||||||
console.log(x.a, x["_$foo$_"]);
|
console.log(x.o, x["_$foo$_"]);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
@@ -49,9 +49,9 @@ issue_1321_with_quoted: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var x = {};
|
var x = {};
|
||||||
x.a = 1;
|
x.o = 1;
|
||||||
x["b"] = 2 * x.a;
|
x["x"] = 2 * x.o;
|
||||||
console.log(x.a, x["b"]);
|
console.log(x.o, x["x"]);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
typeof_eq_undefined: {
|
typeof_eq_undefined: {
|
||||||
options = {
|
options = {
|
||||||
comparisons: true
|
comparisons: true,
|
||||||
|
typeofs: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = typeof b != "undefined";
|
var a = typeof b != "undefined";
|
||||||
@@ -24,6 +25,7 @@ typeof_eq_undefined_ie8: {
|
|||||||
options = {
|
options = {
|
||||||
comparisons: true,
|
comparisons: true,
|
||||||
ie8: true,
|
ie8: true,
|
||||||
|
typeofs: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = typeof b != "undefined";
|
var a = typeof b != "undefined";
|
||||||
@@ -45,7 +47,8 @@ typeof_eq_undefined_ie8: {
|
|||||||
|
|
||||||
undefined_redefined: {
|
undefined_redefined: {
|
||||||
options = {
|
options = {
|
||||||
comparisons: true
|
comparisons: true,
|
||||||
|
typeofs: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f(undefined) {
|
function f(undefined) {
|
||||||
@@ -58,7 +61,8 @@ undefined_redefined: {
|
|||||||
|
|
||||||
undefined_redefined_mangle: {
|
undefined_redefined_mangle: {
|
||||||
options = {
|
options = {
|
||||||
comparisons: true
|
comparisons: true,
|
||||||
|
typeofs: true,
|
||||||
}
|
}
|
||||||
mangle = {}
|
mangle = {}
|
||||||
input: {
|
input: {
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ same_variable_in_multiple_for_loop: {
|
|||||||
console.log(o, l);
|
console.log(o, l);
|
||||||
for (let o = 0; o < 2; o++) {
|
for (let o = 0; o < 2; o++) {
|
||||||
console.log(o, l);
|
console.log(o, l);
|
||||||
let c = 2;
|
let e = 2;
|
||||||
console.log(c);
|
console.log(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -114,12 +114,12 @@ same_variable_in_multiple_forIn: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var test = [ "a", "b", "c" ];
|
var test = [ "a", "b", "c" ];
|
||||||
for (let o in test) {
|
for (let e in test) {
|
||||||
console.log(o);
|
console.log(e);
|
||||||
let e;
|
let t;
|
||||||
e = [ "e", "f", "g" ];
|
t = [ "e", "f", "g" ];
|
||||||
for (let o in test)
|
for (let e in test)
|
||||||
console.log(o);
|
console.log(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
@@ -160,8 +160,8 @@ different_variable_in_multiple_for_loop: {
|
|||||||
console.log(o, l);
|
console.log(o, l);
|
||||||
for (let o = 0; o < 2; o++) {
|
for (let o = 0; o < 2; o++) {
|
||||||
console.log(o, l);
|
console.log(o, l);
|
||||||
let c = 2;
|
let e = 2;
|
||||||
console.log(c);
|
console.log(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -241,12 +241,12 @@ different_variable_in_multiple_forIn: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var test = [ "a", "b", "c" ];
|
var test = [ "a", "b", "c" ];
|
||||||
for (let o in test) {
|
for (let e in test) {
|
||||||
console.log(o);
|
console.log(e);
|
||||||
let e;
|
let t;
|
||||||
e = [ "e", "f", "g" ];
|
t = [ "e", "f", "g" ];
|
||||||
for (let o in test)
|
for (let e in test)
|
||||||
console.log(o);
|
console.log(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
@@ -281,10 +281,10 @@ more_variable_in_multiple_for: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
for (let o = 9, l = 0; l < 20; l += o) {
|
for (let o = 9, l = 0; l < 20; l += o) {
|
||||||
let c = o++ + l;
|
let e = o++ + l;
|
||||||
console.log(o, c, l);
|
console.log(o, e, l);
|
||||||
for (let l = c, e = c * c, f = 0; f < 10; f++)
|
for (let l = e, t = e * e, c = 0; c < 10; c++)
|
||||||
console.log(o, c, e, l, f);
|
console.log(o, e, t, l, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ numeric_literal: {
|
|||||||
' 42: 2,',
|
' 42: 2,',
|
||||||
' "42": 3,',
|
' "42": 3,',
|
||||||
' 37: 4,',
|
' 37: 4,',
|
||||||
' a: 5,',
|
' o: 5,',
|
||||||
' 1e42: 6,',
|
' 1e42: 6,',
|
||||||
' b: 7,',
|
' b: 7,',
|
||||||
' "1e+42": 8',
|
' "1e+42": 8',
|
||||||
@@ -92,7 +92,7 @@ numeric_literal: {
|
|||||||
'',
|
'',
|
||||||
'console.log(obj[42], obj["42"]);',
|
'console.log(obj[42], obj["42"]);',
|
||||||
'',
|
'',
|
||||||
'console.log(obj[37], obj["a"], obj[37], obj["37"]);',
|
'console.log(obj[37], obj["o"], obj[37], obj["37"]);',
|
||||||
'',
|
'',
|
||||||
'console.log(obj[1e42], obj["b"], obj["1e+42"]);',
|
'console.log(obj[1e42], obj["b"], obj["1e+42"]);',
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ export_default_func_1: {
|
|||||||
input: {
|
input: {
|
||||||
export default function f(){};
|
export default function f(){};
|
||||||
}
|
}
|
||||||
expect_exact: "export default function(){};"
|
expect_exact: "export default function f(){};"
|
||||||
}
|
}
|
||||||
|
|
||||||
export_default_func_2: {
|
export_default_func_2: {
|
||||||
@@ -58,7 +58,7 @@ export_default_func_2: {
|
|||||||
input: {
|
input: {
|
||||||
export default function f(){}(1);
|
export default function f(){}(1);
|
||||||
}
|
}
|
||||||
expect_exact: "export default function(){};1;"
|
expect_exact: "export default function f(){};1;"
|
||||||
}
|
}
|
||||||
|
|
||||||
export_default_func_3: {
|
export_default_func_3: {
|
||||||
@@ -71,7 +71,7 @@ export_default_func_3: {
|
|||||||
input: {
|
input: {
|
||||||
export default function f(){}(1);
|
export default function f(){}(1);
|
||||||
}
|
}
|
||||||
expect_exact: "export default function(){};"
|
expect_exact: "export default function f(){};"
|
||||||
}
|
}
|
||||||
|
|
||||||
export_class_1: {
|
export_class_1: {
|
||||||
@@ -121,7 +121,7 @@ export_default_class_1: {
|
|||||||
input: {
|
input: {
|
||||||
export default class C {};
|
export default class C {};
|
||||||
}
|
}
|
||||||
expect_exact: "export default class{};"
|
expect_exact: "export default class C{};"
|
||||||
}
|
}
|
||||||
|
|
||||||
export_default_class_2: {
|
export_default_class_2: {
|
||||||
@@ -134,7 +134,7 @@ export_default_class_2: {
|
|||||||
input: {
|
input: {
|
||||||
export default class C {}(1);
|
export default class C {}(1);
|
||||||
}
|
}
|
||||||
expect_exact: "export default class{};1;"
|
expect_exact: "export default class C{};1;"
|
||||||
}
|
}
|
||||||
|
|
||||||
export_default_class_3: {
|
export_default_class_3: {
|
||||||
@@ -147,7 +147,7 @@ export_default_class_3: {
|
|||||||
input: {
|
input: {
|
||||||
export default class C {}(1);
|
export default class C {}(1);
|
||||||
}
|
}
|
||||||
expect_exact: "export default class{};"
|
expect_exact: "export default class C{};"
|
||||||
}
|
}
|
||||||
|
|
||||||
export_mangle_1: {
|
export_mangle_1: {
|
||||||
@@ -159,7 +159,7 @@ export_mangle_1: {
|
|||||||
return one - two;
|
return one - two;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
expect_exact: "export function foo(n,o){return n-o};"
|
expect_exact: "export function foo(o,n){return o-n};"
|
||||||
}
|
}
|
||||||
|
|
||||||
export_mangle_2: {
|
export_mangle_2: {
|
||||||
@@ -171,7 +171,7 @@ export_mangle_2: {
|
|||||||
return one - two;
|
return one - two;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
expect_exact: "export default function n(n,r){return n-r};"
|
expect_exact: "export default function foo(o,t){return o-t};"
|
||||||
}
|
}
|
||||||
|
|
||||||
export_mangle_3: {
|
export_mangle_3: {
|
||||||
@@ -189,7 +189,7 @@ export_mangle_3: {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
expect_exact: "export class C{go(n,r){return n-r+n}};"
|
expect_exact: "export class C{go(r,e){return r-e+r}};"
|
||||||
}
|
}
|
||||||
|
|
||||||
export_mangle_4: {
|
export_mangle_4: {
|
||||||
@@ -207,7 +207,7 @@ export_mangle_4: {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
expect_exact: "export default class n{go(n,r){return n-r+n}};"
|
expect_exact: "export default class C{go(e,r){return e-r+e}};"
|
||||||
}
|
}
|
||||||
|
|
||||||
export_mangle_5: {
|
export_mangle_5: {
|
||||||
@@ -221,7 +221,7 @@ export_mangle_5: {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
expect_exact: "export default{prop:function(n,r){return n-r}};"
|
expect_exact: "export default{prop:function(r,t){return r-t}};"
|
||||||
}
|
}
|
||||||
|
|
||||||
export_mangle_6: {
|
export_mangle_6: {
|
||||||
@@ -232,7 +232,7 @@ export_mangle_6: {
|
|||||||
var baz = 2;
|
var baz = 2;
|
||||||
export let foo = 1, bar = baz;
|
export let foo = 1, bar = baz;
|
||||||
}
|
}
|
||||||
expect_exact: "var a=2;export let foo=1,bar=a;"
|
expect_exact: "var o=2;export let foo=1,bar=o;"
|
||||||
}
|
}
|
||||||
|
|
||||||
export_toplevel_1: {
|
export_toplevel_1: {
|
||||||
@@ -247,7 +247,7 @@ export_toplevel_1: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
export function g(){};
|
export function g(){};
|
||||||
export default function(){};
|
export default function h(){};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,7 +263,7 @@ export_toplevel_2: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
export class B {};
|
export class B {};
|
||||||
export default class {};
|
export default class C {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ compress_new_function: {
|
|||||||
new Function("aa, bb", 'return aa;');
|
new Function("aa, bb", 'return aa;');
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
Function("a", "b", "return a");
|
Function("n,r", "return n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,8 +27,30 @@ compress_new_function_with_destruct: {
|
|||||||
new Function("[[aa]], [{bb}]", 'return aa;');
|
new Function("[[aa]], [{bb}]", 'return aa;');
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
Function("a", "[b]", "return a");
|
Function("n,[r]", "return n");
|
||||||
Function("a", "{bb:b}", "return a");
|
Function("n,{bb:b}", "return n");
|
||||||
Function("[[a]]", "[{bb:b}]", 'return a');
|
Function("[[n]],[{bb:b}]", "return n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
compress_new_function_with_destruct_arrows: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
unsafe: true,
|
||||||
|
unsafe_Func: true,
|
||||||
|
ecma: 6
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
ecma: 6
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
new Function("aa, [bb]", 'return aa;');
|
||||||
|
new Function("aa, {bb}", 'return aa;');
|
||||||
|
new Function("[[aa]], [{bb}]", 'return aa;');
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
Function("n,[a]", "return n");
|
||||||
|
Function("b,{bb:n}", "return b");
|
||||||
|
Function("[[b]],[{bb:n}]", "return b");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -419,7 +419,7 @@ wrap_iife_in_return_call: {
|
|||||||
expect_exact: '(void console.log("test"))();'
|
expect_exact: '(void console.log("test"))();'
|
||||||
}
|
}
|
||||||
|
|
||||||
pure_annotation: {
|
pure_annotation_1: {
|
||||||
options = {
|
options = {
|
||||||
inline: true,
|
inline: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
@@ -432,6 +432,20 @@ pure_annotation: {
|
|||||||
expect_exact: ""
|
expect_exact: ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pure_annotation_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
/*@__PURE__*/(function(n) {
|
||||||
|
console.log("hello", n);
|
||||||
|
}(42));
|
||||||
|
}
|
||||||
|
expect_exact: ""
|
||||||
|
}
|
||||||
|
|
||||||
drop_fargs: {
|
drop_fargs: {
|
||||||
options = {
|
options = {
|
||||||
cascade: true,
|
cascade: true,
|
||||||
@@ -449,9 +463,7 @@ drop_fargs: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a = 1;
|
var a = 1;
|
||||||
!function() {
|
++a && a.var, a++;
|
||||||
a++;
|
|
||||||
}(++a && a.var);
|
|
||||||
console.log(a);
|
console.log(a);
|
||||||
}
|
}
|
||||||
expect_stdout: "3"
|
expect_stdout: "3"
|
||||||
@@ -474,9 +486,7 @@ keep_fargs: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a = 1;
|
var a = 1;
|
||||||
!function(a_1) {
|
++a && a.var, a++;
|
||||||
a++;
|
|
||||||
}(++a && a.var);
|
|
||||||
console.log(a);
|
console.log(a);
|
||||||
}
|
}
|
||||||
expect_stdout: "3"
|
expect_stdout: "3"
|
||||||
|
|||||||
@@ -1,37 +1,41 @@
|
|||||||
dont_reuse_prop: {
|
dont_reuse_prop: {
|
||||||
mangle_props = {
|
mangle_props = {
|
||||||
regex: /asd/
|
regex: /asd/
|
||||||
};
|
}
|
||||||
|
|
||||||
input: {
|
input: {
|
||||||
|
"aaaaaaaaaabbbbb";
|
||||||
var obj = {};
|
var obj = {};
|
||||||
obj.a = 123;
|
obj.a = 123;
|
||||||
obj.asd = 256;
|
obj.asd = 256;
|
||||||
console.log(obj.a);
|
console.log(obj.a);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
|
"aaaaaaaaaabbbbb";
|
||||||
var obj = {};
|
var obj = {};
|
||||||
obj.a = 123;
|
obj.a = 123;
|
||||||
obj.b = 256;
|
obj.b = 256;
|
||||||
console.log(obj.a);
|
console.log(obj.a);
|
||||||
}
|
}
|
||||||
|
expect_stdout: "123"
|
||||||
}
|
}
|
||||||
|
|
||||||
unmangleable_props_should_always_be_reserved: {
|
unmangleable_props_should_always_be_reserved: {
|
||||||
mangle_props = {
|
mangle_props = {
|
||||||
regex: /asd/
|
regex: /asd/
|
||||||
};
|
}
|
||||||
|
|
||||||
input: {
|
input: {
|
||||||
|
"aaaaaaaaaabbbbb";
|
||||||
var obj = {};
|
var obj = {};
|
||||||
obj.asd = 256;
|
obj.asd = 256;
|
||||||
obj.a = 123;
|
obj.a = 123;
|
||||||
console.log(obj.a);
|
console.log(obj.a);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
|
"aaaaaaaaaabbbbb";
|
||||||
var obj = {};
|
var obj = {};
|
||||||
obj.b = 256;
|
obj.b = 256;
|
||||||
obj.a = 123;
|
obj.a = 123;
|
||||||
console.log(obj.a);
|
console.log(obj.a);
|
||||||
}
|
}
|
||||||
|
expect_stdout: "123"
|
||||||
}
|
}
|
||||||
@@ -480,3 +480,17 @@ do_switch: {
|
|||||||
} while (false);
|
} while (false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
in_parenthesis_1: {
|
||||||
|
input: {
|
||||||
|
for (("foo" in {});0;);
|
||||||
|
}
|
||||||
|
expect_exact: 'for(("foo"in{});0;);'
|
||||||
|
}
|
||||||
|
|
||||||
|
in_parenthesis_2: {
|
||||||
|
input: {
|
||||||
|
for ((function(){ "foo" in {}; });0;);
|
||||||
|
}
|
||||||
|
expect_exact: 'for(function(){"foo"in{}};0;);'
|
||||||
|
}
|
||||||
|
|||||||
@@ -98,3 +98,19 @@ new_with_assignement_expression: {
|
|||||||
new y([a, b] = [3, 4]);
|
new y([a, b] = [3, 4]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dot_parenthesis_1: {
|
||||||
|
input: {
|
||||||
|
console.log(new (Math.random().constructor) instanceof Number);
|
||||||
|
}
|
||||||
|
expect_exact: "console.log(new(Math.random().constructor)instanceof Number);"
|
||||||
|
expect_stdout: "true"
|
||||||
|
}
|
||||||
|
|
||||||
|
dot_parenthesis_2: {
|
||||||
|
input: {
|
||||||
|
console.log(typeof new function(){Math.random()}.constructor);
|
||||||
|
}
|
||||||
|
expect_exact: "console.log(typeof new function(){Math.random()}.constructor);"
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ getter_setter_mangler: {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect_exact: "function f(n,t){return{get:n,set:t,get g(){},set s(n){},c,a:1,m(){}}}"
|
expect_exact: "function f(t,e){return{get:t,set:e,get g(){},set s(t){},c,a:1,m(){}}}"
|
||||||
}
|
}
|
||||||
|
|
||||||
use_shorthand_opportunity: {
|
use_shorthand_opportunity: {
|
||||||
@@ -297,7 +297,7 @@ concise_methods_and_mangle_props: {
|
|||||||
expect: {
|
expect: {
|
||||||
function x() {
|
function x() {
|
||||||
obj = {
|
obj = {
|
||||||
a() { return 1; }
|
o() { return 1; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -510,3 +510,235 @@ variable_as_computed_property: {
|
|||||||
}
|
}
|
||||||
expect_exact: "function getLine(header){return{[header]:{}}}"
|
expect_exact: "function getLine(header){return{[header]:{}}}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prop_func_to_concise_method: {
|
||||||
|
options = {
|
||||||
|
ecma: 6,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
({
|
||||||
|
emit: function NamedFunctionExpression() {
|
||||||
|
console.log("PASS");
|
||||||
|
},
|
||||||
|
run: function() {
|
||||||
|
this.emit();
|
||||||
|
}
|
||||||
|
}).run();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
({
|
||||||
|
emit: function NamedFunctionExpression() {
|
||||||
|
console.log("PASS");
|
||||||
|
},
|
||||||
|
run() {
|
||||||
|
this.emit();
|
||||||
|
}
|
||||||
|
}).run();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
prop_arrow_to_concise_method: {
|
||||||
|
options = {
|
||||||
|
ecma: 6,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
({
|
||||||
|
run: () => {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}).run();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
({
|
||||||
|
run() {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}).run();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
concise_method_to_prop_arrow: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
ecma: 6,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(({ a: () => 1 }).a());
|
||||||
|
console.log(({ a: () => { return 2; } }).a());
|
||||||
|
console.log(({ a() { return 3; } }).a());
|
||||||
|
console.log(({ a() { return this.b; }, b: 4 }).a());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log({ a: () => 1 }.a());
|
||||||
|
console.log({ a: () => 2 }.a());
|
||||||
|
console.log({ a: () => 3 }.a());
|
||||||
|
console.log({ a() { return this.b; }, b: 4 }.a());
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"3",
|
||||||
|
"4",
|
||||||
|
]
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
prop_func_to_async_concise_method: {
|
||||||
|
options = {
|
||||||
|
ecma: 8,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
({
|
||||||
|
run: async function() {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}).run();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
({
|
||||||
|
async run() {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}).run();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
prop_func_to_concise_method_various: {
|
||||||
|
options = {
|
||||||
|
ecma: 6,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
({
|
||||||
|
null: function(x, y){ x(y); },
|
||||||
|
123: function(x, y){ x(y); },
|
||||||
|
"A B": function(x, y){ x(y); },
|
||||||
|
p1: function(x, y){ x(y); },
|
||||||
|
p2: function*(x, y){ yield x(y); },
|
||||||
|
p3: async function(x, y){ await x(y); },
|
||||||
|
[c1]: function(x, y){ x(y); },
|
||||||
|
[c2]: function*(x, y){ yield x(y); },
|
||||||
|
[c3]: async function(x, y){ await x(y); },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
({
|
||||||
|
null(x, y) { x(y); },
|
||||||
|
123(x, y) { x(y); },
|
||||||
|
"A B"(x, y) { x(y); },
|
||||||
|
p1(x, y) { x(y); },
|
||||||
|
*p2(x, y) { yield x(y); },
|
||||||
|
async p3(x, y) { await x(y); },
|
||||||
|
[c1](x, y) { x(y); },
|
||||||
|
*[c2](x, y) { yield x(y); },
|
||||||
|
async [c3](x, y) { await x(y); },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
prop_arrows_to_concise_method_various: {
|
||||||
|
options = {
|
||||||
|
ecma: 6,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
({
|
||||||
|
null: (x, y) => { x(y); },
|
||||||
|
123: (x, y) => { x(y); },
|
||||||
|
"A B": (x, y) => { x(y); },
|
||||||
|
p1: (x, y) => { x(y); },
|
||||||
|
p3: async (x, y) => { await x(y); },
|
||||||
|
[c1]: (x, y) => { x(y); },
|
||||||
|
[c3]: async (x, y) => { await x(y); },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
({
|
||||||
|
null(x, y) { x(y); },
|
||||||
|
123(x, y) { x(y); },
|
||||||
|
"A B"(x, y) { x(y); },
|
||||||
|
p1(x, y) { x(y); },
|
||||||
|
async p3(x, y) { await x(y); },
|
||||||
|
[c1](x, y) { x(y); },
|
||||||
|
async [c3](x, y) { await x(y); },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
prop_arrow_with_this: {
|
||||||
|
options = {
|
||||||
|
ecma: 6,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function run(arg) {
|
||||||
|
console.log(arg === this ? "global" : arg === foo ? "foo" : arg);
|
||||||
|
}
|
||||||
|
var foo = {
|
||||||
|
func_no_this: function() { run(); },
|
||||||
|
func_with_this: function() { run(this); },
|
||||||
|
arrow_no_this: () => { run(); },
|
||||||
|
arrow_with_this: () => { run(this); },
|
||||||
|
};
|
||||||
|
for (var key in foo) foo[key]();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function run(arg) {
|
||||||
|
console.log(arg === this ? "global" : arg === foo ? "foo" : arg);
|
||||||
|
}
|
||||||
|
var foo = {
|
||||||
|
func_no_this() { run(); },
|
||||||
|
func_with_this() { run(this); },
|
||||||
|
arrow_no_this() { run(); },
|
||||||
|
arrow_with_this: () => { run(this); },
|
||||||
|
};
|
||||||
|
for (var key in foo) foo[key]();
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"undefined",
|
||||||
|
"foo",
|
||||||
|
"undefined",
|
||||||
|
"global",
|
||||||
|
]
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
prop_arrow_with_nested_this: {
|
||||||
|
options = {
|
||||||
|
ecma: 6,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function run(arg) {
|
||||||
|
console.log(arg === this ? "global" : arg === foo ? "foo" : arg);
|
||||||
|
}
|
||||||
|
var foo = {
|
||||||
|
func_func_this: function() { (function() { run(this); })(); },
|
||||||
|
func_arrow_this: function() { (() => { run(this); })(); },
|
||||||
|
arrow_func_this: () => { (function() { run(this); })(); },
|
||||||
|
arrow_arrow_this: () => { (() => { run(this); })(); },
|
||||||
|
};
|
||||||
|
for (var key in foo) foo[key]();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function run(arg) {
|
||||||
|
console.log(arg === this ? "global" : arg === foo ? "foo" : arg);
|
||||||
|
}
|
||||||
|
var foo = {
|
||||||
|
func_func_this() { (function() { run(this); })(); },
|
||||||
|
func_arrow_this() { (() => { run(this); })(); },
|
||||||
|
arrow_func_this() { (function() { run(this); })(); },
|
||||||
|
arrow_arrow_this: () => { (() => { run(this); })(); },
|
||||||
|
};
|
||||||
|
for (var key in foo) foo[key]();
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"global",
|
||||||
|
"foo",
|
||||||
|
"global",
|
||||||
|
"global",
|
||||||
|
]
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
arrow_functions: {
|
arrow_functions: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
(a) => b; // 1 args
|
(a) => b; // 1 args
|
||||||
(a, b) => c; // n args
|
(a, b) => c; // n args
|
||||||
@@ -13,6 +16,9 @@ arrow_functions: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
arrow_return: {
|
arrow_return: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
() => {};
|
() => {};
|
||||||
() => { return; };
|
() => { return; };
|
||||||
|
|||||||
@@ -13,8 +13,10 @@ keep_properties: {
|
|||||||
dot_properties: {
|
dot_properties: {
|
||||||
options = {
|
options = {
|
||||||
properties: true,
|
properties: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
ie8: true,
|
ie8: true,
|
||||||
};
|
}
|
||||||
input: {
|
input: {
|
||||||
a["foo"] = "bar";
|
a["foo"] = "bar";
|
||||||
a["if"] = "if";
|
a["if"] = "if";
|
||||||
@@ -36,8 +38,10 @@ dot_properties: {
|
|||||||
dot_properties_es5: {
|
dot_properties_es5: {
|
||||||
options = {
|
options = {
|
||||||
properties: true,
|
properties: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
ie8: false,
|
ie8: false,
|
||||||
};
|
}
|
||||||
input: {
|
input: {
|
||||||
a["foo"] = "bar";
|
a["foo"] = "bar";
|
||||||
a["if"] = "if";
|
a["if"] = "if";
|
||||||
@@ -135,11 +139,11 @@ mangle_properties: {
|
|||||||
a['run']({color: "blue", foo: "baz"});
|
a['run']({color: "blue", foo: "baz"});
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
a["a"] = "bar";
|
a["o"] = "bar";
|
||||||
a.b = "red";
|
a.a = "red";
|
||||||
x = {c: 10};
|
x = {r: 10};
|
||||||
a.d(x.c, a.a);
|
a.b(x.r, a.o);
|
||||||
a['d']({b: "blue", a: "baz"});
|
a['b']({a: "blue", o: "baz"});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,16 +182,16 @@ mangle_unquoted_properties: {
|
|||||||
function f1() {
|
function f1() {
|
||||||
a["foo"] = "bar";
|
a["foo"] = "bar";
|
||||||
a.color = "red";
|
a.color = "red";
|
||||||
a.b = 2;
|
a.o = 2;
|
||||||
x = {"bar": 10, c: 7};
|
x = {"bar": 10, f: 7};
|
||||||
a.c = 9;
|
a.f = 9;
|
||||||
}
|
}
|
||||||
function f2() {
|
function f2() {
|
||||||
a.foo = "bar";
|
a.foo = "bar";
|
||||||
a['color'] = "red";
|
a['color'] = "red";
|
||||||
x = {bar: 10, c: 7};
|
x = {bar: 10, f: 7};
|
||||||
a.c = 9;
|
a.f = 9;
|
||||||
a.b = 3;
|
a.o = 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -659,3 +663,210 @@ accessor_this: {
|
|||||||
expect_exact: 'var a=1;var b={get this(){return a},set this(c){a=c}};console.log(b.this,b.this=2,b.this);'
|
expect_exact: 'var a=1;var b={get this(){return a},set this(c){a=c}};console.log(b.this,b.this=2,b.this);'
|
||||||
expect_stdout: "1 2 2"
|
expect_stdout: "1 2 2"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2208_1: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
side_effects: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log({
|
||||||
|
p: function() {
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
}.p());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(42);
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2208_2: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
side_effects: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log({
|
||||||
|
a: 42,
|
||||||
|
p: function() {
|
||||||
|
return this.a;
|
||||||
|
}
|
||||||
|
}.p());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log({
|
||||||
|
a: 42,
|
||||||
|
p: function() {
|
||||||
|
return this.a;
|
||||||
|
}
|
||||||
|
}.p());
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2208_3: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
side_effects: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
a = 42;
|
||||||
|
console.log({
|
||||||
|
p: function() {
|
||||||
|
return function() {
|
||||||
|
return this.a;
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
}.p());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
a = 42;
|
||||||
|
console.log(function() {
|
||||||
|
return this.a;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2208_4: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
side_effects: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function foo() {}
|
||||||
|
console.log({
|
||||||
|
a: foo(),
|
||||||
|
p: function() {
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
}.p());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function foo() {}
|
||||||
|
console.log((foo(), function() {
|
||||||
|
return 42;
|
||||||
|
})());
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2208_5: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
side_effects: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log({
|
||||||
|
p: "FAIL",
|
||||||
|
p: function() {
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
}.p());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(42);
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2208_6: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
side_effects: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log({
|
||||||
|
p: () => 42
|
||||||
|
}.p());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(42);
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2208_7: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
side_effects: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log({
|
||||||
|
p() {
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
}.p());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(42);
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2208_8: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
side_effects: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log({
|
||||||
|
*p() {
|
||||||
|
return x();
|
||||||
|
}
|
||||||
|
}.p());
|
||||||
|
console.log({
|
||||||
|
async p() {
|
||||||
|
return await x();
|
||||||
|
}
|
||||||
|
}.p());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log({
|
||||||
|
*p() {
|
||||||
|
return x();
|
||||||
|
}
|
||||||
|
}.p());
|
||||||
|
console.log(async function() {
|
||||||
|
return await x();
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2208_9: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
side_effects: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
a = 42;
|
||||||
|
console.log({
|
||||||
|
p: () => {
|
||||||
|
return function() {
|
||||||
|
return this.a;
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
}.p());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
a = 42;
|
||||||
|
console.log(function() {
|
||||||
|
return this.a;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|||||||
@@ -178,3 +178,210 @@ impure_getter_2: {
|
|||||||
}
|
}
|
||||||
expect: {}
|
expect: {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2110_1: {
|
||||||
|
options = {
|
||||||
|
cascade: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
function f() {}
|
||||||
|
function g() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
f.g = g;
|
||||||
|
return f.g();
|
||||||
|
}
|
||||||
|
console.log(typeof f());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
function f() {}
|
||||||
|
return f.g = function() {
|
||||||
|
return this;
|
||||||
|
}, f.g();
|
||||||
|
}
|
||||||
|
console.log(typeof f());
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2110_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
function f() {}
|
||||||
|
function g() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
f.g = g;
|
||||||
|
return f.g();
|
||||||
|
}
|
||||||
|
console.log(typeof f());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
function f() {}
|
||||||
|
f.g = function() {
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
return f.g();
|
||||||
|
}
|
||||||
|
console.log(typeof f());
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|
||||||
|
set_immutable_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 1;
|
||||||
|
a.foo += "";
|
||||||
|
if (a.foo) console.log("FAIL");
|
||||||
|
else console.log("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
1..foo += "";
|
||||||
|
if (1..foo) console.log("FAIL");
|
||||||
|
else console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
set_immutable_2: {
|
||||||
|
options = {
|
||||||
|
cascade: true,
|
||||||
|
conditionals: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 1;
|
||||||
|
a.foo += "";
|
||||||
|
if (a.foo) console.log("FAIL");
|
||||||
|
else console.log("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 1;
|
||||||
|
a.foo += "", a.foo ? console.log("FAIL") : console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
set_immutable_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
var a = 1;
|
||||||
|
a.foo += "";
|
||||||
|
if (a.foo) console.log("FAIL");
|
||||||
|
else console.log("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
1..foo += "";
|
||||||
|
if (1..foo) console.log("FAIL");
|
||||||
|
else console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
set_immutable_4: {
|
||||||
|
options = {
|
||||||
|
cascade: true,
|
||||||
|
conditionals: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
var a = 1;
|
||||||
|
a.foo += "";
|
||||||
|
if (a.foo) console.log("FAIL");
|
||||||
|
else console.log("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
var a = 1;
|
||||||
|
a.foo += "", a.foo ? console.log("FAIL") : console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
set_mutable_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function a() {
|
||||||
|
a.foo += "";
|
||||||
|
if (a.foo) console.log("PASS");
|
||||||
|
else console.log("FAIL");
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function a() {
|
||||||
|
if (a.foo += "") console.log("PASS");
|
||||||
|
else console.log("FAIL");
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
set_mutable_2: {
|
||||||
|
options = {
|
||||||
|
cascade: true,
|
||||||
|
conditionals: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function a() {
|
||||||
|
a.foo += "";
|
||||||
|
if (a.foo) console.log("PASS");
|
||||||
|
else console.log("FAIL");
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function a() {
|
||||||
|
(a.foo += "") ? console.log("PASS") : console.log("FAIL");
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1469,6 +1469,7 @@ issue_1670_1: {
|
|||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
switches: true,
|
switches: true,
|
||||||
|
typeofs: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -1532,6 +1533,7 @@ issue_1670_3: {
|
|||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
switches: true,
|
switches: true,
|
||||||
|
typeofs: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -2625,3 +2627,28 @@ issue_2090_2: {
|
|||||||
expect_stdout: "1"
|
expect_stdout: "1"
|
||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for_in_prop: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = {
|
||||||
|
foo: function() {
|
||||||
|
for (this.b in [1, 2]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
a.foo();
|
||||||
|
console.log(a.b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = {
|
||||||
|
foo: function() {
|
||||||
|
for (this.b in [1, 2]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
a.foo();
|
||||||
|
console.log(a.b);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|||||||
@@ -255,3 +255,73 @@ issue_1586_2: {
|
|||||||
}
|
}
|
||||||
expect_exact: "function f(){try{x()}catch(c){console.log(c.message)}}"
|
expect_exact: "function f(){try{x()}catch(c){console.log(c.message)}}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2120_1: {
|
||||||
|
mangle = {
|
||||||
|
ie8: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"aaaaaaaa";
|
||||||
|
var a = 1, b = "FAIL";
|
||||||
|
try {
|
||||||
|
throw 1;
|
||||||
|
} catch (c) {
|
||||||
|
try {
|
||||||
|
throw 0;
|
||||||
|
} catch (a) {
|
||||||
|
if (c) b = "PASS";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"aaaaaaaa";
|
||||||
|
var a = 1, b = "FAIL";
|
||||||
|
try {
|
||||||
|
throw 1;
|
||||||
|
} catch (t) {
|
||||||
|
try {
|
||||||
|
throw 0;
|
||||||
|
} catch (a) {
|
||||||
|
if (t) b = "PASS";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2120_2: {
|
||||||
|
mangle = {
|
||||||
|
ie8: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"aaaaaaaa";
|
||||||
|
var a = 1, b = "FAIL";
|
||||||
|
try {
|
||||||
|
throw 1;
|
||||||
|
} catch (c) {
|
||||||
|
try {
|
||||||
|
throw 0;
|
||||||
|
} catch (a) {
|
||||||
|
if (c) b = "PASS";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"aaaaaaaa";
|
||||||
|
var a = 1, b = "FAIL";
|
||||||
|
try {
|
||||||
|
throw 1;
|
||||||
|
} catch (c) {
|
||||||
|
try {
|
||||||
|
throw 0;
|
||||||
|
} catch (a) {
|
||||||
|
if (c) b = "PASS";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -176,6 +176,11 @@ for_sequences: {
|
|||||||
// 4
|
// 4
|
||||||
x = (foo in bar);
|
x = (foo in bar);
|
||||||
for (y = 5; false;);
|
for (y = 5; false;);
|
||||||
|
// 5
|
||||||
|
x = function() {
|
||||||
|
foo in bar;
|
||||||
|
};
|
||||||
|
for (y = 5; false;);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
// 1
|
// 1
|
||||||
@@ -188,6 +193,10 @@ for_sequences: {
|
|||||||
// 4
|
// 4
|
||||||
x = (foo in bar);
|
x = (foo in bar);
|
||||||
for (y = 5; false;);
|
for (y = 5; false;);
|
||||||
|
// 5
|
||||||
|
for (x = function() {
|
||||||
|
foo in bar;
|
||||||
|
}, y = 5; false;);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
3
test/input/invalid/export_1.js
Normal file
3
test/input/invalid/export_1.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
export var V = 1;
|
||||||
|
}
|
||||||
1
test/input/invalid/export_2.js
Normal file
1
test/input/invalid/export_2.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export class{};
|
||||||
1
test/input/invalid/export_3.js
Normal file
1
test/input/invalid/export_3.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export function(){};
|
||||||
4
test/input/invalid/for-in_1.js
Normal file
4
test/input/invalid/for-in_1.js
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
var a, b = [1, 2];
|
||||||
|
for (1, 2, a in b) {
|
||||||
|
console.log(a, b[a]);
|
||||||
|
}
|
||||||
4
test/input/invalid/for-in_2.js
Normal file
4
test/input/invalid/for-in_2.js
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
var c = [1, 2];
|
||||||
|
for (var a, b in c) {
|
||||||
|
console.log(a, c[a]);
|
||||||
|
}
|
||||||
3
test/input/invalid/import.js
Normal file
3
test/input/invalid/import.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
import A from "B";
|
||||||
|
}
|
||||||
1
test/input/invalid/sequence.js
Normal file
1
test/input/invalid/sequence.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
(a, ...b);
|
||||||
@@ -62,23 +62,20 @@ describe("Arrow functions", function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
it("Should not accept arrow functions in the middle or end of an expression", function() {
|
it("Should not accept arrow functions in the middle or end of an expression", function() {
|
||||||
var tests = [
|
[
|
||||||
|
"0 + x => 0",
|
||||||
|
"0 + async x => 0",
|
||||||
"typeof x => 0",
|
"typeof x => 0",
|
||||||
"0 + x => 0"
|
"typeof async x => 0",
|
||||||
];
|
"typeof (x) => null",
|
||||||
var test = function(code) {
|
"typeof async (x) => null",
|
||||||
return function() {
|
].forEach(function(code) {
|
||||||
|
assert.throws(function() {
|
||||||
uglify.parse(code);
|
uglify.parse(code);
|
||||||
}
|
}, function(e) {
|
||||||
}
|
return e instanceof uglify.JS_Parse_Error && /^Unexpected /.test(e.message);
|
||||||
var error = function(e) {
|
}, code);
|
||||||
return e instanceof uglify.JS_Parse_Error &&
|
});
|
||||||
e.message === "Unexpected token: arrow (=>)";
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < tests.length; i++) {
|
|
||||||
assert.throws(test(tests[i]), error);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should parse a function containing default assignment correctly", function() {
|
it("Should parse a function containing default assignment correctly", function() {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
var exec = require("child_process").exec;
|
var exec = require("child_process").exec;
|
||||||
var readFileSync = require("fs").readFileSync;
|
var readFileSync = require("fs").readFileSync;
|
||||||
|
var semver = require("semver");
|
||||||
|
|
||||||
function read(path) {
|
function read(path) {
|
||||||
return readFileSync(path, "utf8");
|
return readFileSync(path, "utf8");
|
||||||
@@ -9,9 +10,11 @@ function read(path) {
|
|||||||
describe("bin/uglifyjs", function () {
|
describe("bin/uglifyjs", function () {
|
||||||
var uglifyjscmd = '"' + process.argv[0] + '" bin/uglifyjs';
|
var uglifyjscmd = '"' + process.argv[0] + '" bin/uglifyjs';
|
||||||
it("should produce a functional build when using --self", function (done) {
|
it("should produce a functional build when using --self", function (done) {
|
||||||
this.timeout(30000);
|
this.timeout(60000);
|
||||||
|
|
||||||
var command = uglifyjscmd + ' --self -cm --wrap WrappedUglifyJS';
|
var command = uglifyjscmd + ' --self -mc ecma=';
|
||||||
|
command += semver.satisfies(process.version, ">=4") ? "6" : "5";
|
||||||
|
command += ',passes=3,keep_fargs=false,unsafe --wrap WrappedUglifyJS';
|
||||||
|
|
||||||
exec(command, function (err, stdout) {
|
exec(command, function (err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
@@ -63,7 +66,7 @@ describe("bin/uglifyjs", function () {
|
|||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
assert.strictEqual(stdout, "var bar=function(){function foo(bar){return bar}return foo}();\n" +
|
assert.strictEqual(stdout, "var bar=function(){function foo(bar){return bar}return foo}();\n" +
|
||||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxJQUdYLE9BQU9DIn0=\n");
|
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxJQUdYLE9BQU9DLElBTEQifQ==\n");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -192,7 +195,7 @@ describe("bin/uglifyjs", function () {
|
|||||||
|
|
||||||
assert.strictEqual(stdout, [
|
assert.strictEqual(stdout, [
|
||||||
"var bar=function(){function foo(bar){return bar}return foo}();",
|
"var bar=function(){function foo(bar){return bar}return foo}();",
|
||||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxJQUdYLE9BQU9DIn0=",
|
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxJQUdYLE9BQU9DLElBTEQifQ==",
|
||||||
"",
|
"",
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
assert.strictEqual(stderr, "WARN: inline source map not found\n");
|
assert.strictEqual(stderr, "WARN: inline source map not found\n");
|
||||||
@@ -533,6 +536,111 @@ describe("bin/uglifyjs", function () {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
it("Should throw syntax error (block-level export)", function(done) {
|
||||||
|
var command = uglifyjscmd + ' test/input/invalid/export_1.js -m';
|
||||||
|
|
||||||
|
exec(command, function (err, stdout, stderr) {
|
||||||
|
assert.ok(err);
|
||||||
|
assert.strictEqual(stdout, "");
|
||||||
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
|
"Parse error at test/input/invalid/export_1.js:2,4",
|
||||||
|
" export var V = 1;",
|
||||||
|
" ^",
|
||||||
|
"ERROR: Export statement may only appear at top level"
|
||||||
|
].join("\n"));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should throw syntax error (block-level import)", function(done) {
|
||||||
|
var command = uglifyjscmd + ' test/input/invalid/import.js -m';
|
||||||
|
|
||||||
|
exec(command, function (err, stdout, stderr) {
|
||||||
|
assert.ok(err);
|
||||||
|
assert.strictEqual(stdout, "");
|
||||||
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
|
"Parse error at test/input/invalid/import.js:2,4",
|
||||||
|
' import A from "B";',
|
||||||
|
" ^",
|
||||||
|
"ERROR: Import statement may only appear at top level"
|
||||||
|
].join("\n"));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should throw syntax error (anonymous class)", function(done) {
|
||||||
|
var command = uglifyjscmd + ' test/input/invalid/export_2.js';
|
||||||
|
|
||||||
|
exec(command, function (err, stdout, stderr) {
|
||||||
|
assert.ok(err);
|
||||||
|
assert.strictEqual(stdout, "");
|
||||||
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
|
"Parse error at test/input/invalid/export_2.js:1,12",
|
||||||
|
"export class{};",
|
||||||
|
" ^",
|
||||||
|
"ERROR: Unexpected token: punc ({)"
|
||||||
|
].join("\n"));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should throw syntax error (anonymous function)", function(done) {
|
||||||
|
var command = uglifyjscmd + ' test/input/invalid/export_3.js';
|
||||||
|
|
||||||
|
exec(command, function (err, stdout, stderr) {
|
||||||
|
assert.ok(err);
|
||||||
|
assert.strictEqual(stdout, "");
|
||||||
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
|
"Parse error at test/input/invalid/export_3.js:1,15",
|
||||||
|
"export function(){};",
|
||||||
|
" ^",
|
||||||
|
"ERROR: Unexpected token: punc (()"
|
||||||
|
].join("\n"));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should throw syntax error (spread in sequence)", function(done) {
|
||||||
|
var command = uglifyjscmd + ' test/input/invalid/sequence.js';
|
||||||
|
|
||||||
|
exec(command, function (err, stdout, stderr) {
|
||||||
|
assert.ok(err);
|
||||||
|
assert.strictEqual(stdout, "");
|
||||||
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
|
"Parse error at test/input/invalid/sequence.js:1,4",
|
||||||
|
"(a, ...b);",
|
||||||
|
" ^",
|
||||||
|
"ERROR: Unexpected token: expand (...)"
|
||||||
|
].join("\n"));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should throw syntax error (for-in init)", function(done) {
|
||||||
|
var command = uglifyjscmd + ' test/input/invalid/for-in_1.js';
|
||||||
|
|
||||||
|
exec(command, function (err, stdout, stderr) {
|
||||||
|
assert.ok(err);
|
||||||
|
assert.strictEqual(stdout, "");
|
||||||
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
|
"Parse error at test/input/invalid/for-in_1.js:2,5",
|
||||||
|
"for (1, 2, a in b) {",
|
||||||
|
" ^",
|
||||||
|
"ERROR: Invalid left-hand side in for..in loop"
|
||||||
|
].join("\n"));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should throw syntax error (for-in var)", function(done) {
|
||||||
|
var command = uglifyjscmd + ' test/input/invalid/for-in_2.js';
|
||||||
|
|
||||||
|
exec(command, function (err, stdout, stderr) {
|
||||||
|
assert.ok(err);
|
||||||
|
assert.strictEqual(stdout, "");
|
||||||
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
|
"Parse error at test/input/invalid/for-in_2.js:2,5",
|
||||||
|
"for (var a, b in c) {",
|
||||||
|
" ^",
|
||||||
|
"ERROR: Only one variable declaration allowed in for..in loop"
|
||||||
|
].join("\n"));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
it("Should handle literal string as source map input", function(done) {
|
it("Should handle literal string as source map input", function(done) {
|
||||||
var command = [
|
var command = [
|
||||||
uglifyjscmd,
|
uglifyjscmd,
|
||||||
@@ -578,8 +686,8 @@ describe("bin/uglifyjs", function () {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should work with --mangle reserved=[]", function (done) {
|
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 -m reserved=[callback]";
|
||||||
|
|
||||||
exec(command, function (err, stdout) {
|
exec(command, function (err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
@@ -588,8 +696,8 @@ describe("bin/uglifyjs", function () {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should work with --mangle reserved=false", function (done) {
|
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 -m reserved=false";
|
||||||
|
|
||||||
exec(command, function (err, stdout) {
|
exec(command, function (err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
@@ -598,4 +706,22 @@ describe("bin/uglifyjs", function () {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
it("Should fail with --mangle-props reserved=[in]", function(done) {
|
||||||
|
var command = uglifyjscmd + " test/input/issue-505/input.js --mangle-props reserved=[in]";
|
||||||
|
exec(command, function (err, stdout, stderr) {
|
||||||
|
assert.ok(err);
|
||||||
|
assert.strictEqual(stdout, "");
|
||||||
|
assert.ok(/^Supported options:\n[\s\S]*?\nERROR: `reserved=\[in]` is not a supported option/.test(stderr), stderr);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should fail with --define a-b", function(done) {
|
||||||
|
var command = uglifyjscmd + " test/input/issue-505/input.js --define a-b";
|
||||||
|
exec(command, function (err, stdout, stderr) {
|
||||||
|
assert.ok(err);
|
||||||
|
assert.strictEqual(stdout, "");
|
||||||
|
assert.strictEqual(stderr, "Error parsing arguments for 'define': a-b\n");
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,8 +2,7 @@ var assert = require("assert");
|
|||||||
var uglify = require("../node");
|
var uglify = require("../node");
|
||||||
|
|
||||||
describe("Export", function() {
|
describe("Export", function() {
|
||||||
it ("Should parse export directives", function() {
|
it("Should parse export directives", function() {
|
||||||
|
|
||||||
var inputs = [
|
var inputs = [
|
||||||
['export * from "a.js"', ['*'], "a.js"],
|
['export * from "a.js"', ['*'], "a.js"],
|
||||||
['export {A} from "a.js"', ['A'], "a.js"],
|
['export {A} from "a.js"', ['A'], "a.js"],
|
||||||
@@ -12,17 +11,17 @@ describe("Export", function() {
|
|||||||
['export {A, B} from "a.js"', ['A', 'B'], "a.js"],
|
['export {A, B} from "a.js"', ['A', 'B'], "a.js"],
|
||||||
];
|
];
|
||||||
|
|
||||||
var test = function(code) {
|
function test(code) {
|
||||||
return uglify.parse(code);
|
return uglify.parse(code);
|
||||||
};
|
}
|
||||||
|
|
||||||
var extractNames = function(symbols) {
|
function extractNames(symbols) {
|
||||||
var ret = [];
|
var ret = [];
|
||||||
for (var i = 0; i < symbols.length; i++) {
|
for (var i = 0; i < symbols.length; i++) {
|
||||||
ret.push(symbols[i].name.name)
|
ret.push(symbols[i].foreign_name.name);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
};
|
}
|
||||||
|
|
||||||
for (var i = 0; i < inputs.length; i++) {
|
for (var i = 0; i < inputs.length; i++) {
|
||||||
var ast = test(inputs[i][0]);
|
var ast = test(inputs[i][0]);
|
||||||
@@ -34,7 +33,7 @@ describe("Export", function() {
|
|||||||
assert(st instanceof uglify.AST_Export);
|
assert(st instanceof uglify.AST_Export);
|
||||||
var actualNames = extractNames(st.exported_names);
|
var actualNames = extractNames(st.exported_names);
|
||||||
assert.deepEqual(actualNames, names);
|
assert.deepEqual(actualNames, names);
|
||||||
assert.equal(st.module_name.value, filename)
|
assert.equal(st.module_name.value, filename);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
});
|
});
|
||||||
@@ -191,15 +191,51 @@ describe("Function", function() {
|
|||||||
];
|
];
|
||||||
var test = function(code) {
|
var test = function(code) {
|
||||||
return function() {
|
return function() {
|
||||||
uglify.parse(code);
|
uglify.parse(code, { ecma: 5 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var error = function(e) {
|
var error = function(e) {
|
||||||
return e instanceof uglify.JS_Parse_Error &&
|
return e instanceof uglify.JS_Parse_Error;
|
||||||
e.message === "Invalid function parameter";
|
|
||||||
}
|
}
|
||||||
for (var i = 0; i < tests.length; i++) {
|
for (var i = 0; i < tests.length; i++) {
|
||||||
assert.throws(test(tests[i]), error);
|
assert.throws(test(tests[i]), error, tests[i]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
it("Should accept trailing commas only for ES8", function() {
|
||||||
|
[
|
||||||
|
"new Foo(a, );",
|
||||||
|
"async(...[1, 2], );",
|
||||||
|
"console.log(...[1, 2], );",
|
||||||
|
"!function(a, b, ){ console.log(a + b); }(3, 4, );",
|
||||||
|
].forEach(function(code) {
|
||||||
|
uglify.parse(code, { ecma: 8 });
|
||||||
|
assert.throws(function() {
|
||||||
|
uglify.parse(code, { ecma: 6 });
|
||||||
|
}, function(e) {
|
||||||
|
return e instanceof uglify.JS_Parse_Error;
|
||||||
|
}, code);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should not accept invalid trailing commas", function() {
|
||||||
|
var tests = [
|
||||||
|
"f(, );",
|
||||||
|
"(, ) => {};",
|
||||||
|
"(...p, ) => {};",
|
||||||
|
"function f(, ) {}",
|
||||||
|
"function f(...p, ) {}",
|
||||||
|
"function foo(a, b, , ) {}",
|
||||||
|
'console.log("hello", , );',
|
||||||
|
];
|
||||||
|
var test = function(code) {
|
||||||
|
return function() {
|
||||||
|
uglify.parse(code, { ecma: 8 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var error = function(e) {
|
||||||
|
return e instanceof uglify.JS_Parse_Error;
|
||||||
|
}
|
||||||
|
for (var i = 0; i < tests.length; i++) {
|
||||||
|
assert.throws(test(tests[i]), error, tests[i]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
it("Should not accept an initializer when parameter is a rest parameter", function() {
|
it("Should not accept an initializer when parameter is a rest parameter", function() {
|
||||||
|
|||||||
@@ -26,12 +26,12 @@ describe("bin/uglifyjs with input file globs", function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("bin/uglifyjs with multiple input file globs.", function(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';
|
var command = uglifyjscmd + ' "test/input/issue-1242/???.es5" "test/input/issue-1242/*.js" -mc toplevel,passes=2';
|
||||||
|
|
||||||
exec(command, function(err, stdout) {
|
exec(command, function(err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
assert.strictEqual(stdout, 'var print=console.log.bind(console);print("qux",9,6),print("Foo:",2*11);\n');
|
assert.strictEqual(stdout, 'var print=console.log.bind(console);print("qux",9,6),print("Foo:",22);\n');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,29 +2,56 @@ var Uglify = require('../../');
|
|||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
|
|
||||||
describe("let", function() {
|
describe("let", function() {
|
||||||
it("Should not produce `let` as a variable name in mangle", function(done) {
|
this.timeout(30000);
|
||||||
this.timeout(10000);
|
it("Should not produce reserved keywords as variable name in mangle", function() {
|
||||||
|
|
||||||
// Produce a lot of variables in a function and run it through mangle.
|
// Produce a lot of variables in a function and run it through mangle.
|
||||||
var s = '"use strict"; function foo() {';
|
var s = '"dddddeeeeelllllooooottttt"; function foo() {';
|
||||||
for (var i = 0; i < 21000; ++i) {
|
for (var i = 0; i < 18000; i++) {
|
||||||
s += "var v" + i + "=0;";
|
s += "var v" + i + "=0;";
|
||||||
}
|
}
|
||||||
s += '}';
|
s += '}';
|
||||||
var result = Uglify.minify(s, {compress: false});
|
var result = Uglify.minify(s, {
|
||||||
|
compress: false
|
||||||
|
}).code;
|
||||||
|
|
||||||
// Verify that select keywords and reserved keywords not produced
|
// Verify that select keywords and reserved keywords not produced
|
||||||
assert.strictEqual(result.code.indexOf("var let="), -1);
|
[
|
||||||
assert.strictEqual(result.code.indexOf("var do="), -1);
|
"do",
|
||||||
assert.strictEqual(result.code.indexOf("var var="), -1);
|
"let",
|
||||||
|
"var",
|
||||||
|
].forEach(function(name) {
|
||||||
|
assert.strictEqual(result.indexOf("var " + name + "="), -1);
|
||||||
|
});
|
||||||
|
|
||||||
// Verify that the variable names that appeared immediately before
|
// Verify that the variable names that appeared immediately before
|
||||||
// and after the erroneously generated `let` variable name still exist
|
// and after the erroneously generated variable name still exist
|
||||||
// to show the test generated enough symbols.
|
// to show the test generated enough symbols.
|
||||||
assert(result.code.indexOf("var ket=") >= 0);
|
[
|
||||||
assert(result.code.indexOf("var met=") >= 0);
|
"to", "eo",
|
||||||
|
"eet", "fet",
|
||||||
done();
|
"rar", "oar",
|
||||||
|
].forEach(function(name) {
|
||||||
|
assert.notStrictEqual(result.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 + ";";
|
||||||
|
}
|
||||||
|
var result = Uglify.minify(s, {
|
||||||
|
compress: false,
|
||||||
|
ie8: true,
|
||||||
|
mangle: {
|
||||||
|
properties: true,
|
||||||
|
}
|
||||||
|
}).code;
|
||||||
|
[
|
||||||
|
"in",
|
||||||
|
"var",
|
||||||
|
].forEach(function(name) {
|
||||||
|
assert.notStrictEqual(result.indexOf(name), -1);
|
||||||
|
assert.notStrictEqual(result.indexOf('v["' + name + '"]'), -1);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
var Uglify = require('../../');
|
var Uglify = require('../../');
|
||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
var readFileSync = require("fs").readFileSync;
|
var readFileSync = require("fs").readFileSync;
|
||||||
|
var run_code = require("../sandbox").run_code;
|
||||||
|
|
||||||
function read(path) {
|
function read(path) {
|
||||||
return readFileSync(path, "utf8");
|
return readFileSync(path, "utf8");
|
||||||
@@ -20,6 +21,58 @@ describe("minify", function() {
|
|||||||
assert.strictEqual(result.code, "alert(2);");
|
assert.strictEqual(result.code, "alert(2);");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Should work with mangle.cache", function() {
|
||||||
|
var cache = {};
|
||||||
|
var original = "";
|
||||||
|
var compressed = "";
|
||||||
|
[
|
||||||
|
"bar.es5",
|
||||||
|
"baz.es5",
|
||||||
|
"foo.es5",
|
||||||
|
"qux.js",
|
||||||
|
].forEach(function(file) {
|
||||||
|
var code = read("test/input/issue-1242/" + file);
|
||||||
|
var result = Uglify.minify(code, {
|
||||||
|
mangle: {
|
||||||
|
cache: cache,
|
||||||
|
toplevel: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
original += code;
|
||||||
|
compressed += result.code;
|
||||||
|
});
|
||||||
|
assert.strictEqual(JSON.stringify(cache).slice(0, 20), '{"cname":5,"props":{');
|
||||||
|
assert.strictEqual(compressed, 'function n(n){return 3*n}function r(n){return n/2}function c(o){l("Foo:",2*o)}var l=console.log.bind(console);var f=n(3),i=r(12);l("qux",f,i),c(11);');
|
||||||
|
assert.strictEqual(run_code(compressed), run_code(original));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should work with nameCache", function() {
|
||||||
|
var cache = {};
|
||||||
|
var original = "";
|
||||||
|
var compressed = "";
|
||||||
|
[
|
||||||
|
"bar.es5",
|
||||||
|
"baz.es5",
|
||||||
|
"foo.es5",
|
||||||
|
"qux.js",
|
||||||
|
].forEach(function(file) {
|
||||||
|
var code = read("test/input/issue-1242/" + file);
|
||||||
|
var result = Uglify.minify(code, {
|
||||||
|
mangle: {
|
||||||
|
toplevel: true
|
||||||
|
},
|
||||||
|
nameCache: cache
|
||||||
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
original += code;
|
||||||
|
compressed += result.code;
|
||||||
|
});
|
||||||
|
assert.strictEqual(JSON.stringify(cache).slice(0, 28), '{"vars":{"cname":5,"props":{');
|
||||||
|
assert.strictEqual(compressed, 'function n(n){return 3*n}function r(n){return n/2}function c(o){l("Foo:",2*o)}var l=console.log.bind(console);var f=n(3),i=r(12);l("qux",f,i),c(11);');
|
||||||
|
assert.strictEqual(run_code(compressed), run_code(original));
|
||||||
|
});
|
||||||
|
|
||||||
describe("keep_quoted_props", function() {
|
describe("keep_quoted_props", function() {
|
||||||
it("Should preserve quotes in object literals", function() {
|
it("Should preserve quotes in object literals", function() {
|
||||||
var js = 'var foo = {"x": 1, y: 2, \'z\': 3};';
|
var js = 'var foo = {"x": 1, y: 2, \'z\': 3};';
|
||||||
@@ -212,7 +265,7 @@ describe("minify", function() {
|
|||||||
});
|
});
|
||||||
var err = result.error;
|
var err = result.error;
|
||||||
assert.ok(err instanceof Error);
|
assert.ok(err instanceof Error);
|
||||||
assert.strictEqual(err.stack.split(/\n/)[0], "Error: Can't handle expression: debugger");
|
assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: Unexpected token: keyword (debugger)");
|
||||||
});
|
});
|
||||||
it("should skip inherited properties", function() {
|
it("should skip inherited properties", function() {
|
||||||
var foo = Object.create({ skip: this });
|
var foo = Object.create({ skip: this });
|
||||||
|
|||||||
@@ -4,7 +4,11 @@ var assert = require("assert");
|
|||||||
describe("Object", function() {
|
describe("Object", function() {
|
||||||
it("Should allow objects to have a methodDefinition as property", function() {
|
it("Should allow objects to have a methodDefinition as property", function() {
|
||||||
var code = "var a = {test() {return true;}}";
|
var code = "var a = {test() {return true;}}";
|
||||||
assert.equal(Uglify.minify(code).code, "var a={test(){return!0}};");
|
assert.equal(Uglify.minify(code, {
|
||||||
|
compress: {
|
||||||
|
arrows: false
|
||||||
|
}
|
||||||
|
}).code, "var a={test(){return!0}};");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should not allow objects to use static keywords like in classes", function() {
|
it("Should not allow objects to use static keywords like in classes", function() {
|
||||||
|
|||||||
@@ -30,4 +30,13 @@ describe("Template string", function() {
|
|||||||
assert.throws(exec(tests[i]), fail, tests[i]);
|
assert.throws(exec(tests[i]), fail, tests[i]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
it("Should process all line terminators as LF", function() {
|
||||||
|
[
|
||||||
|
"`a\rb`",
|
||||||
|
"`a\nb`",
|
||||||
|
"`a\r\nb`",
|
||||||
|
].forEach(function(code) {
|
||||||
|
assert.strictEqual(uglify.parse(code).print_to_string(), "`a\\nb`;");
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -86,7 +86,6 @@ function run_compress_tests() {
|
|||||||
log_start_file(file);
|
log_start_file(file);
|
||||||
function test_case(test) {
|
function test_case(test) {
|
||||||
log_test(test.name);
|
log_test(test.name);
|
||||||
U.base54.reset();
|
|
||||||
var output_options = test.beautify || {};
|
var output_options = test.beautify || {};
|
||||||
var expect;
|
var expect;
|
||||||
if (test.expect) {
|
if (test.expect) {
|
||||||
@@ -101,9 +100,6 @@ function run_compress_tests() {
|
|||||||
quote_style: 3,
|
quote_style: 3,
|
||||||
keep_quoted_props: true
|
keep_quoted_props: true
|
||||||
});
|
});
|
||||||
if (test.mangle_props) {
|
|
||||||
input = U.mangle_properties(input, test.mangle_props);
|
|
||||||
}
|
|
||||||
var options = U.defaults(test.options, {
|
var options = U.defaults(test.options, {
|
||||||
warnings: false
|
warnings: false
|
||||||
});
|
});
|
||||||
@@ -118,10 +114,16 @@ function run_compress_tests() {
|
|||||||
var cmp = new U.Compressor(options, true);
|
var cmp = new U.Compressor(options, true);
|
||||||
var output = cmp.compress(input);
|
var output = cmp.compress(input);
|
||||||
output.figure_out_scope(test.mangle);
|
output.figure_out_scope(test.mangle);
|
||||||
if (test.mangle) {
|
if (test.mangle || test.mangle_props) {
|
||||||
|
U.base54.reset();
|
||||||
output.compute_char_frequency(test.mangle);
|
output.compute_char_frequency(test.mangle);
|
||||||
|
}
|
||||||
|
if (test.mangle) {
|
||||||
output.mangle_names(test.mangle);
|
output.mangle_names(test.mangle);
|
||||||
}
|
}
|
||||||
|
if (test.mangle_props) {
|
||||||
|
output = U.mangle_properties(output, test.mangle_props);
|
||||||
|
}
|
||||||
output = make_code(output, output_options);
|
output = make_code(output, output_options);
|
||||||
if (expect != output) {
|
if (expect != output) {
|
||||||
log("!!! failed\n---INPUT---\n{input}\n---OUTPUT---\n{output}\n---EXPECTED---\n{expected}\n\n", {
|
log("!!! failed\n---INPUT---\n{input}\n---OUTPUT---\n{output}\n---EXPECTED---\n{expected}\n\n", {
|
||||||
|
|||||||
Reference in New Issue
Block a user