Compare commits
74 Commits
harmony-v3
...
v3.1.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6920e898d1 | ||
|
|
dd71639264 | ||
|
|
2dcc552ce0 | ||
|
|
55387e8fd0 | ||
|
|
7e3e9da860 | ||
|
|
00f509405b | ||
|
|
aceb0af36b | ||
|
|
4f0953f7e9 | ||
|
|
182a47bfb1 | ||
|
|
cd27f4ec38 | ||
|
|
8158b1bdcf | ||
|
|
aacf3edc68 | ||
|
|
8b89072190 | ||
|
|
395a17ccda | ||
|
|
3f355866cf | ||
|
|
71d52f147d | ||
|
|
eb7adaa6fc | ||
|
|
e5cf7972ea | ||
|
|
f81ff10a9b | ||
|
|
16d40915b4 | ||
|
|
e7c21e87e3 | ||
|
|
c4c2ef44d0 | ||
|
|
a845897758 | ||
|
|
32ea2c5530 | ||
|
|
bc61deeca9 | ||
|
|
6a5e74b44e | ||
|
|
54446341ee | ||
|
|
4e12a6f740 | ||
|
|
b35dfc2599 | ||
|
|
9e1da9235e | ||
|
|
a5ffe2c23f | ||
|
|
9282e7b0c6 | ||
|
|
5229cb2b1b | ||
|
|
458e3e15f0 | ||
|
|
c615a1e80a | ||
|
|
10a938cb79 | ||
|
|
4956ad311b | ||
|
|
145874e504 | ||
|
|
bd7be07c38 | ||
|
|
71ee91e716 | ||
|
|
4f70d2e28c | ||
|
|
4b6ca5e742 | ||
|
|
9306da3c58 | ||
|
|
1ac25fc032 | ||
|
|
5f046c724b | ||
|
|
af0262b7e5 | ||
|
|
6b3aeff1d8 | ||
|
|
20e4f8277f | ||
|
|
f3a487a368 | ||
|
|
2dde41615a | ||
|
|
8b69a3d18e | ||
|
|
d40950b741 | ||
|
|
7659ea1d2e | ||
|
|
bdeadffbf5 | ||
|
|
5e6f26445f | ||
|
|
f0a99125ee | ||
|
|
1e4de2e6d3 | ||
|
|
8b4dcd8f3e | ||
|
|
285401ced8 | ||
|
|
9db4c42380 | ||
|
|
94e5e00c03 | ||
|
|
dc6bcaa18e | ||
|
|
d58b184835 | ||
|
|
b3a57ff019 | ||
|
|
3d5bc08185 | ||
|
|
0692435f01 | ||
|
|
f67a6b0e43 | ||
|
|
343ea326c2 | ||
|
|
1c150c632f | ||
|
|
0a0f4f5591 | ||
|
|
931daa85bf | ||
|
|
00e4f7b3c1 | ||
|
|
11e63bc335 | ||
|
|
33405bb24b |
9
.github/ISSUE_TEMPLATE.md
vendored
9
.github/ISSUE_TEMPLATE.md
vendored
@@ -8,7 +8,14 @@
|
|||||||
|
|
||||||
**Uglify version (`uglifyjs -V`)**
|
**Uglify version (`uglifyjs -V`)**
|
||||||
|
|
||||||
**JavaScript input** <!-- ideally as small as possible -->
|
**JavaScript input**
|
||||||
|
|
||||||
|
<!--
|
||||||
|
A complete parsable JS program exhibiting the issue with
|
||||||
|
UglifyJS alone - without third party tools or libraries.
|
||||||
|
Ideally the input should be as small as possible.
|
||||||
|
Post a link to a gist if necessary.
|
||||||
|
-->
|
||||||
|
|
||||||
**The `uglifyjs` CLI command executed or `minify()` options used.**
|
**The `uglifyjs` CLI command executed or `minify()` options used.**
|
||||||
|
|
||||||
|
|||||||
100
README.md
100
README.md
@@ -111,7 +111,7 @@ a double dash to prevent input files being used as option arguments:
|
|||||||
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.
|
||||||
@@ -150,19 +150,19 @@ debugging your compressed JavaScript. To get a source map, pass
|
|||||||
|
|
||||||
Additional options:
|
Additional options:
|
||||||
|
|
||||||
- `--source-map filename=<NAME>` to specify the name of the source map.
|
- `--source-map "filename='<NAME>'"` to specify the name of the source map.
|
||||||
|
|
||||||
- `--source-map root=<URL>` to pass the URL where the original files can be found.
|
- `--source-map "root='<URL>'"` to pass the URL where the original files can be found.
|
||||||
Otherwise UglifyJS assumes HTTP `X-SourceMap` is being used and will omit the
|
Otherwise UglifyJS assumes HTTP `X-SourceMap` is being used and will omit the
|
||||||
`//# sourceMappingURL=` directive.
|
`//# sourceMappingURL=` directive.
|
||||||
|
|
||||||
- `--source-map url=<URL>` to specify the URL where the source map can be found.
|
- `--source-map "url='<URL>'"` to specify the URL where the source map can be found.
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
uglifyjs js/file1.js js/file2.js \
|
uglifyjs js/file1.js js/file2.js \
|
||||||
-o foo.min.js -c -m \
|
-o foo.min.js -c -m \
|
||||||
--source-map root="http://foo.com/src",url=foo.min.js.map
|
--source-map "root='http://foo.com/src',url='foo.min.js.map'"
|
||||||
|
|
||||||
The above will compress and mangle `file1.js` and `file2.js`, will drop the
|
The above will compress and mangle `file1.js` and `file2.js`, will drop the
|
||||||
output in `foo.min.js` and the source map in `foo.min.js.map`. The source
|
output in `foo.min.js` and the source map in `foo.min.js.map`. The source
|
||||||
@@ -181,8 +181,8 @@ CoffeeScript → compiled JS, UglifyJS can generate a map from CoffeeScript →
|
|||||||
compressed JS by mapping every token in the compiled JS to its original
|
compressed JS by mapping every token in the compiled JS to its original
|
||||||
location.
|
location.
|
||||||
|
|
||||||
To use this feature pass `--source-map content="/path/to/input/source.map"`
|
To use this feature pass `--source-map "content='/path/to/input/source.map'"`
|
||||||
or `--source-map content=inline` if the source map is included inline with
|
or `--source-map "content=inline"` if the source map is included inline with
|
||||||
the sources.
|
the sources.
|
||||||
|
|
||||||
## CLI compress options
|
## CLI compress options
|
||||||
@@ -213,7 +213,7 @@ When mangling is enabled but you want to prevent certain names from being
|
|||||||
mangled, you can declare those names with `--mangle reserved` — pass a
|
mangled, you can declare those names with `--mangle reserved` — pass a
|
||||||
comma-separated list of names. For example:
|
comma-separated list of names. For example:
|
||||||
|
|
||||||
uglifyjs ... -m reserved=[$,require,exports]
|
uglifyjs ... -m reserved=['$','require','exports']
|
||||||
|
|
||||||
to prevent the `require`, `exports` and `$` names from being changed.
|
to prevent the `require`, `exports` and `$` names from being changed.
|
||||||
|
|
||||||
@@ -383,7 +383,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:
|
||||||
@@ -461,6 +501,13 @@ 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
|
||||||
@@ -487,6 +534,7 @@ if (result.error) throw result.error;
|
|||||||
sourceMap: {
|
sourceMap: {
|
||||||
// source map options
|
// source map options
|
||||||
},
|
},
|
||||||
|
nameCache: null, // or specify a name cache object
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
ie8: false,
|
ie8: false,
|
||||||
}
|
}
|
||||||
@@ -596,6 +644,10 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
|||||||
- `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
|
||||||
|
|
||||||
@@ -669,7 +721,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.
|
||||||
|
|
||||||
@@ -825,7 +877,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)
|
||||||
@@ -978,3 +1029,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 });
|
||||||
|
```
|
||||||
|
|||||||
49
bin/uglifyjs
49
bin/uglifyjs
@@ -35,11 +35,11 @@ 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.");
|
||||||
@@ -106,17 +106,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 +257,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 +310,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 +328,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 +351,18 @@ function parse_js(flag, constants) {
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
} catch(ex) {
|
} catch(ex) {
|
||||||
options[value] = null;
|
if (flag) {
|
||||||
|
fatal("Error parsing arguments for '" + flag + "': " + value);
|
||||||
|
} else {
|
||||||
|
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 +374,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;
|
||||||
}
|
}
|
||||||
|
|||||||
13
lib/ast.js
13
lib/ast.js
@@ -134,11 +134,10 @@ var AST_Debugger = DEFNODE("Debugger", null, {
|
|||||||
$documentation: "Represents a debugger statement",
|
$documentation: "Represents a debugger statement",
|
||||||
}, AST_Statement);
|
}, AST_Statement);
|
||||||
|
|
||||||
var AST_Directive = DEFNODE("Directive", "value scope quote", {
|
var AST_Directive = DEFNODE("Directive", "value quote", {
|
||||||
$documentation: "Represents a directive, like \"use strict\";",
|
$documentation: "Represents a directive, like \"use strict\";",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
value: "[string] The value of this directive as a plain string (it's not an AST_String!)",
|
value: "[string] The value of this directive as a plain string (it's not an AST_String!)",
|
||||||
scope: "[AST_Scope/S] The scope that this directive affects",
|
|
||||||
quote: "[string] the original quote character"
|
quote: "[string] the original quote character"
|
||||||
},
|
},
|
||||||
}, AST_Statement);
|
}, AST_Statement);
|
||||||
@@ -299,10 +298,9 @@ var AST_With = DEFNODE("With", "expression", {
|
|||||||
|
|
||||||
/* -----[ scope and functions ]----- */
|
/* -----[ scope and functions ]----- */
|
||||||
|
|
||||||
var AST_Scope = DEFNODE("Scope", "directives variables functions uses_with uses_eval parent_scope enclosed cname", {
|
var AST_Scope = DEFNODE("Scope", "variables functions uses_with uses_eval parent_scope enclosed cname", {
|
||||||
$documentation: "Base class for all statements introducing a lexical scope",
|
$documentation: "Base class for all statements introducing a lexical scope",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
directives: "[string*/S] an array of directives declared in this scope",
|
|
||||||
variables: "[Object/S] a map of name -> SymbolDef for all variables/functions defined in this scope",
|
variables: "[Object/S] a map of name -> SymbolDef for all variables/functions defined in this scope",
|
||||||
functions: "[Object/S] like `variables`, but only lists function declarations",
|
functions: "[Object/S] like `variables`, but only lists function declarations",
|
||||||
uses_with: "[boolean/S] tells whether this scope uses the `with` statement",
|
uses_with: "[boolean/S] tells whether this scope uses the `with` statement",
|
||||||
@@ -859,7 +857,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) {
|
||||||
@@ -873,9 +871,8 @@ TreeWalker.prototype = {
|
|||||||
}
|
}
|
||||||
this.stack.push(node);
|
this.stack.push(node);
|
||||||
},
|
},
|
||||||
pop: function(node) {
|
pop: function() {
|
||||||
this.stack.pop();
|
if (this.stack.pop() instanceof AST_Lambda) {
|
||||||
if (node instanceof AST_Lambda) {
|
|
||||||
this.directives = Object.getPrototypeOf(this.directives);
|
this.directives = Object.getPrototypeOf(this.directives);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
1161
lib/compress.js
1161
lib/compress.js
File diff suppressed because it is too large
Load Diff
@@ -27,6 +27,23 @@ 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 {
|
||||||
@@ -35,6 +52,7 @@ function minify(files, options) {
|
|||||||
ie8: false,
|
ie8: false,
|
||||||
keep_fnames: false,
|
keep_fnames: false,
|
||||||
mangle: {},
|
mangle: {},
|
||||||
|
nameCache: null,
|
||||||
output: {},
|
output: {},
|
||||||
parse: {},
|
parse: {},
|
||||||
sourceMap: false,
|
sourceMap: false,
|
||||||
@@ -50,9 +68,10 @@ function minify(files, options) {
|
|||||||
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" ]);
|
||||||
|
var quoted_props;
|
||||||
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_fnames: false,
|
keep_fnames: false,
|
||||||
@@ -60,6 +79,21 @@ function minify(files, options) {
|
|||||||
reserved: [],
|
reserved: [],
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}, true);
|
}, true);
|
||||||
|
if (options.mangle.properties) {
|
||||||
|
if (typeof options.mangle.properties != "object") {
|
||||||
|
options.mangle.properties = {};
|
||||||
|
}
|
||||||
|
if (options.mangle.properties.keep_quoted) {
|
||||||
|
quoted_props = options.mangle.properties.reserved;
|
||||||
|
if (!Array.isArray(quoted_props)) quoted_props = [];
|
||||||
|
options.mangle.properties.reserved = quoted_props;
|
||||||
|
}
|
||||||
|
if (options.nameCache && !("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, {
|
||||||
@@ -97,6 +131,9 @@ function minify(files, options) {
|
|||||||
}
|
}
|
||||||
toplevel = options.parse.toplevel;
|
toplevel = options.parse.toplevel;
|
||||||
}
|
}
|
||||||
|
if (quoted_props) {
|
||||||
|
reserve_quoted_keys(toplevel, quoted_props);
|
||||||
|
}
|
||||||
if (options.wrap) {
|
if (options.wrap) {
|
||||||
toplevel = toplevel.wrap_commonjs(options.wrap);
|
toplevel = toplevel.wrap_commonjs(options.wrap);
|
||||||
}
|
}
|
||||||
@@ -153,6 +190,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 = {
|
||||||
|
|||||||
104
lib/output.js
104
lib/output.js
@@ -109,7 +109,7 @@ function OutputStream(options) {
|
|||||||
var current_pos = 0;
|
var current_pos = 0;
|
||||||
var OUTPUT = "";
|
var OUTPUT = "";
|
||||||
|
|
||||||
function to_ascii(str, identifier) {
|
var to_utf8 = options.ascii_only ? function(str, identifier) {
|
||||||
return str.replace(/[\u0000-\u001f\u007f-\uffff]/g, function(ch) {
|
return str.replace(/[\u0000-\u001f\u007f-\uffff]/g, function(ch) {
|
||||||
var code = ch.charCodeAt(0).toString(16);
|
var code = ch.charCodeAt(0).toString(16);
|
||||||
if (code.length <= 2 && !identifier) {
|
if (code.length <= 2 && !identifier) {
|
||||||
@@ -120,6 +120,12 @@ function OutputStream(options) {
|
|||||||
return "\\u" + code;
|
return "\\u" + code;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} : function(str) {
|
||||||
|
return str.replace(/[\ud800-\udbff](?![\udc00-\udfff])/g, function(ch) {
|
||||||
|
return "\\u" + ch.charCodeAt(0).toString(16);
|
||||||
|
}).replace(/(^|[^\ud800-\udbff])([\udc00-\udfff])/g, function(match, prefix, ch) {
|
||||||
|
return prefix + "\\u" + ch.charCodeAt(0).toString(16);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function make_string(str, quote) {
|
function make_string(str, quote) {
|
||||||
@@ -140,7 +146,7 @@ function OutputStream(options) {
|
|||||||
case "\u2029": return "\\u2029";
|
case "\u2029": return "\\u2029";
|
||||||
case "\ufeff": return "\\ufeff";
|
case "\ufeff": return "\\ufeff";
|
||||||
case "\0":
|
case "\0":
|
||||||
return /[0-7]/.test(str.charAt(i+1)) ? "\\x00" : "\\0";
|
return /[0-9]/.test(str.charAt(i+1)) ? "\\x00" : "\\0";
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
});
|
});
|
||||||
@@ -150,7 +156,7 @@ function OutputStream(options) {
|
|||||||
function quote_double() {
|
function quote_double() {
|
||||||
return '"' + str.replace(/\x22/g, '\\"') + '"';
|
return '"' + str.replace(/\x22/g, '\\"') + '"';
|
||||||
}
|
}
|
||||||
if (options.ascii_only) str = to_ascii(str);
|
str = to_utf8(str);
|
||||||
switch (options.quote_style) {
|
switch (options.quote_style) {
|
||||||
case 1:
|
case 1:
|
||||||
return quote_single();
|
return quote_single();
|
||||||
@@ -175,8 +181,7 @@ function OutputStream(options) {
|
|||||||
|
|
||||||
function make_name(name) {
|
function make_name(name) {
|
||||||
name = name.toString();
|
name = name.toString();
|
||||||
if (options.ascii_only)
|
name = to_utf8(name, true);
|
||||||
name = to_ascii(name, true);
|
|
||||||
return name;
|
return name;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -433,7 +438,7 @@ function OutputStream(options) {
|
|||||||
last : function() { return last },
|
last : function() { return last },
|
||||||
semicolon : semicolon,
|
semicolon : semicolon,
|
||||||
force_semicolon : force_semicolon,
|
force_semicolon : force_semicolon,
|
||||||
to_ascii : to_ascii,
|
to_utf8 : to_utf8,
|
||||||
print_name : function(name) { print(make_name(name)) },
|
print_name : function(name) { print(make_name(name)) },
|
||||||
print_string : function(str, quote, escape_directive) {
|
print_string : function(str, quote, escape_directive) {
|
||||||
var encoded = encode_string(str, quote);
|
var encoded = encode_string(str, quote);
|
||||||
@@ -477,13 +482,17 @@ function OutputStream(options) {
|
|||||||
nodetype.DEFMETHOD("_codegen", generator);
|
nodetype.DEFMETHOD("_codegen", generator);
|
||||||
};
|
};
|
||||||
|
|
||||||
var use_asm = false;
|
|
||||||
var in_directive = false;
|
var in_directive = false;
|
||||||
|
var active_scope = null;
|
||||||
|
var use_asm = null;
|
||||||
|
|
||||||
AST_Node.DEFMETHOD("print", function(stream, force_parens){
|
AST_Node.DEFMETHOD("print", function(stream, force_parens){
|
||||||
var self = this, generator = self._codegen, prev_use_asm = use_asm;
|
var self = this, generator = self._codegen;
|
||||||
if (self instanceof AST_Directive && self.value == "use asm" && stream.parent() instanceof AST_Scope) {
|
if (self instanceof AST_Scope) {
|
||||||
use_asm = true;
|
active_scope = self;
|
||||||
|
}
|
||||||
|
else if (!use_asm && self instanceof AST_Directive && self.value == "use asm") {
|
||||||
|
use_asm = active_scope;
|
||||||
}
|
}
|
||||||
function doit() {
|
function doit() {
|
||||||
self.add_comments(stream);
|
self.add_comments(stream);
|
||||||
@@ -497,10 +506,11 @@ function OutputStream(options) {
|
|||||||
doit();
|
doit();
|
||||||
}
|
}
|
||||||
stream.pop_node();
|
stream.pop_node();
|
||||||
if (self instanceof AST_Scope) {
|
if (self === use_asm) {
|
||||||
use_asm = prev_use_asm;
|
use_asm = null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
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);
|
||||||
@@ -671,14 +681,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;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1072,19 +1083,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
|
if (noin) node.walk(new TreeWalker(function(node) {
|
||||||
node.walk(new TreeWalker(function(node){
|
if (parens || node instanceof AST_Scope) return true;
|
||||||
if (node instanceof AST_Binary && node.operator == "in")
|
if (node instanceof AST_Binary && node.operator == "in") {
|
||||||
throw output;
|
parens = true;
|
||||||
}));
|
return true;
|
||||||
node.print(output);
|
}
|
||||||
} catch(ex) {
|
}));
|
||||||
if (ex !== output) throw ex;
|
node.print(output, parens);
|
||||||
node.print(output, true);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
DEFPRINT(AST_VarDef, function(self, output){
|
DEFPRINT(AST_VarDef, function(self, output){
|
||||||
@@ -1104,6 +1113,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_Call || 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();
|
||||||
@@ -1143,15 +1155,23 @@ 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);
|
||||||
if (expr instanceof AST_Number && expr.getValue() >= 0) {
|
var prop = self.property;
|
||||||
if (!/[xa-f.)]/i.test(output.last())) {
|
if (output.option("ie8") && RESERVED_WORDS(prop)) {
|
||||||
output.print(".");
|
output.print("[");
|
||||||
|
output.add_mapping(self.end);
|
||||||
|
output.print_string(prop);
|
||||||
|
output.print("]");
|
||||||
|
} else {
|
||||||
|
if (expr instanceof AST_Number && expr.getValue() >= 0) {
|
||||||
|
if (!/[xa-f.)]/i.test(output.last())) {
|
||||||
|
output.print(".");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
output.print(".");
|
||||||
|
// the name after dot would be mapped about here.
|
||||||
|
output.add_mapping(self.end);
|
||||||
|
output.print_name(prop);
|
||||||
}
|
}
|
||||||
output.print(".");
|
|
||||||
// the name after dot would be mapped about here.
|
|
||||||
output.add_mapping(self.end);
|
|
||||||
output.print_name(self.property);
|
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_Sub, function(self, output){
|
DEFPRINT(AST_Sub, function(self, output){
|
||||||
self.expression.print(output);
|
self.expression.print(output);
|
||||||
@@ -1307,9 +1327,7 @@ function OutputStream(options) {
|
|||||||
if (regexp.raw_source) {
|
if (regexp.raw_source) {
|
||||||
str = "/" + regexp.raw_source + str.slice(str.lastIndexOf("/"));
|
str = "/" + regexp.raw_source + str.slice(str.lastIndexOf("/"));
|
||||||
}
|
}
|
||||||
if (output.option("ascii_only")) {
|
str = output.to_utf8(str);
|
||||||
str = output.to_ascii(str);
|
|
||||||
}
|
|
||||||
output.print(str);
|
output.print(str);
|
||||||
var p = output.parent();
|
var p = output.parent();
|
||||||
if (p instanceof AST_Binary && /^in/.test(p.operator) && p.left === self)
|
if (p instanceof AST_Binary && /^in/.test(p.operator) && p.left === self)
|
||||||
|
|||||||
10
lib/parse.js
10
lib/parse.js
@@ -1010,8 +1010,12 @@ function parse($TEXT, options) {
|
|||||||
? (next(), var_(true))
|
? (next(), var_(true))
|
||||||
: expression(true, true);
|
: expression(true, true);
|
||||||
if (is("operator", "in")) {
|
if (is("operator", "in")) {
|
||||||
if (init instanceof AST_Var && init.definitions.length > 1)
|
if (init instanceof AST_Var) {
|
||||||
croak("Only one variable declaration allowed in for..in loop");
|
if (init.definitions.length > 1)
|
||||||
|
croak("Only one variable declaration allowed in for..in loop", init.start.line, init.start.col, init.start.pos);
|
||||||
|
} else if (!is_assignable(init)) {
|
||||||
|
croak("Invalid left-hand side in for..in loop", init.start.line, init.start.col, init.start.pos);
|
||||||
|
}
|
||||||
next();
|
next();
|
||||||
return for_in(init);
|
return for_in(init);
|
||||||
}
|
}
|
||||||
@@ -1050,6 +1054,8 @@ function parse($TEXT, options) {
|
|||||||
var name = is("name") ? as_symbol(in_statement ? AST_SymbolDefun : AST_SymbolLambda) : null;
|
var name = is("name") ? as_symbol(in_statement ? AST_SymbolDefun : AST_SymbolLambda) : null;
|
||||||
if (in_statement && !name)
|
if (in_statement && !name)
|
||||||
unexpected();
|
unexpected();
|
||||||
|
if (name && ctor !== AST_Accessor && !(name instanceof AST_SymbolDeclaration))
|
||||||
|
unexpected(prev());
|
||||||
expect("(");
|
expect("(");
|
||||||
var argnames = [];
|
var argnames = [];
|
||||||
for (var first = true; !is("punc", ")");) {
|
for (var first = true; !is("punc", ")");) {
|
||||||
|
|||||||
@@ -67,6 +67,34 @@ function find_builtins(reserved) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function reserve_quoted_keys(ast, reserved) {
|
||||||
|
function add(name) {
|
||||||
|
push_uniq(reserved, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
ast.walk(new TreeWalker(function(node) {
|
||||||
|
if (node instanceof AST_ObjectKeyVal && node.quote) {
|
||||||
|
add(node.key);
|
||||||
|
} else if (node instanceof AST_Sub) {
|
||||||
|
addStrings(node.property, add);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
function addStrings(node, add) {
|
||||||
|
node.walk(new TreeWalker(function(node) {
|
||||||
|
if (node instanceof AST_Sequence) {
|
||||||
|
addStrings(node.expressions[node.expressions.length - 1], add);
|
||||||
|
} else if (node instanceof AST_String) {
|
||||||
|
add(node.value);
|
||||||
|
} else if (node instanceof AST_Conditional) {
|
||||||
|
addStrings(node.consequent, add);
|
||||||
|
addStrings(node.alternative, add);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
function mangle_properties(ast, options) {
|
function mangle_properties(ast, options) {
|
||||||
options = defaults(options, {
|
options = defaults(options, {
|
||||||
builtins: false,
|
builtins: false,
|
||||||
@@ -76,7 +104,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 = [];
|
||||||
@@ -91,7 +119,6 @@ function mangle_properties(ast, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var regex = options.regex;
|
var regex = options.regex;
|
||||||
var keep_quoted = options.keep_quoted;
|
|
||||||
|
|
||||||
// note debug is either false (disabled), or a string of the debug suffix to use (enabled).
|
// note debug is either false (disabled), or a string of the debug suffix to use (enabled).
|
||||||
// note debug may be enabled as an empty string, which is falsey. Also treat passing 'true'
|
// note debug may be enabled as an empty string, which is falsey. Also treat passing 'true'
|
||||||
@@ -104,12 +131,11 @@ function mangle_properties(ast, options) {
|
|||||||
|
|
||||||
var names_to_mangle = [];
|
var names_to_mangle = [];
|
||||||
var unmangleable = [];
|
var unmangleable = [];
|
||||||
var to_keep = {};
|
|
||||||
|
|
||||||
// step 1: find candidates to mangle
|
// step 1: find candidates to mangle
|
||||||
ast.walk(new TreeWalker(function(node){
|
ast.walk(new TreeWalker(function(node){
|
||||||
if (node instanceof AST_ObjectKeyVal) {
|
if (node instanceof AST_ObjectKeyVal) {
|
||||||
add(node.key, keep_quoted && node.quote);
|
add(node.key);
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_ObjectProperty) {
|
else if (node instanceof AST_ObjectProperty) {
|
||||||
// setter or getter, since KeyVal is handled above
|
// setter or getter, since KeyVal is handled above
|
||||||
@@ -119,15 +145,14 @@ function mangle_properties(ast, options) {
|
|||||||
add(node.property);
|
add(node.property);
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_Sub) {
|
else if (node instanceof AST_Sub) {
|
||||||
addStrings(node.property, keep_quoted);
|
addStrings(node.property, add);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// step 2: transform the tree, renaming properties
|
// step 2: transform the tree, renaming properties
|
||||||
return ast.transform(new TreeTransformer(function(node){
|
return ast.transform(new TreeTransformer(function(node){
|
||||||
if (node instanceof AST_ObjectKeyVal) {
|
if (node instanceof AST_ObjectKeyVal) {
|
||||||
if (!(keep_quoted && node.quote))
|
node.key = mangle(node.key);
|
||||||
node.key = mangle(node.key);
|
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_ObjectProperty) {
|
else if (node instanceof AST_ObjectProperty) {
|
||||||
// setter or getter
|
// setter or getter
|
||||||
@@ -136,22 +161,9 @@ function mangle_properties(ast, options) {
|
|||||||
else if (node instanceof AST_Dot) {
|
else if (node instanceof AST_Dot) {
|
||||||
node.property = mangle(node.property);
|
node.property = mangle(node.property);
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_Sub) {
|
else if (!options.keep_quoted && node instanceof AST_Sub) {
|
||||||
if (!keep_quoted)
|
node.property = mangleStrings(node.property);
|
||||||
node.property = mangleStrings(node.property);
|
|
||||||
}
|
}
|
||||||
// else if (node instanceof AST_String) {
|
|
||||||
// if (should_mangle(node.value)) {
|
|
||||||
// AST_Node.warn(
|
|
||||||
// "Found \"{prop}\" property candidate for mangling in an arbitrary string [{file}:{line},{col}]", {
|
|
||||||
// file : node.start.file,
|
|
||||||
// line : node.start.line,
|
|
||||||
// col : node.start.col,
|
|
||||||
// prop : node.value
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// only function declarations after this line
|
// only function declarations after this line
|
||||||
@@ -167,19 +179,13 @@ function mangle_properties(ast, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function should_mangle(name) {
|
function should_mangle(name) {
|
||||||
if (keep_quoted && name in to_keep) return false;
|
|
||||||
if (regex && !regex.test(name)) return false;
|
if (regex && !regex.test(name)) return false;
|
||||||
if (reserved.indexOf(name) >= 0) return false;
|
if (reserved.indexOf(name) >= 0) return false;
|
||||||
return cache.props.has(name)
|
return cache.props.has(name)
|
||||||
|| names_to_mangle.indexOf(name) >= 0;
|
|| names_to_mangle.indexOf(name) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function add(name, keep) {
|
function add(name) {
|
||||||
if (keep) {
|
|
||||||
to_keep[name] = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (can_mangle(name))
|
if (can_mangle(name))
|
||||||
push_uniq(names_to_mangle, name);
|
push_uniq(names_to_mangle, name);
|
||||||
|
|
||||||
@@ -199,19 +205,16 @@ function mangle_properties(ast, options) {
|
|||||||
// debug mode: use a prefix and suffix to preserve readability, e.g. o.foo -> o._$foo$NNN_.
|
// debug mode: use a prefix and suffix to preserve readability, e.g. o.foo -> o._$foo$NNN_.
|
||||||
var debug_mangled = "_$" + name + "$" + debug_name_suffix + "_";
|
var debug_mangled = "_$" + name + "$" + debug_name_suffix + "_";
|
||||||
|
|
||||||
if (can_mangle(debug_mangled) && !(keep_quoted && debug_mangled in to_keep)) {
|
if (can_mangle(debug_mangled)) {
|
||||||
mangled = debug_mangled;
|
mangled = debug_mangled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// either debug mode is off, or it is on and we could not use the mangled name
|
// either debug mode is off, or it is on and we could not use the mangled name
|
||||||
if (!mangled) {
|
if (!mangled) {
|
||||||
// Note: `can_mangle()` does not check if the name collides with the `to_keep` set
|
|
||||||
// (filled with quoted properties when `keep_quoted` is set). Make sure we add this
|
|
||||||
// check so we don't collide with a quoted name.
|
|
||||||
do {
|
do {
|
||||||
mangled = base54(++cache.cname);
|
mangled = base54(++cache.cname);
|
||||||
} while (!can_mangle(mangled) || keep_quoted && mangled in to_keep);
|
} while (!can_mangle(mangled));
|
||||||
}
|
}
|
||||||
|
|
||||||
cache.props.set(name, mangled);
|
cache.props.set(name, mangled);
|
||||||
@@ -219,32 +222,6 @@ function mangle_properties(ast, options) {
|
|||||||
return mangled;
|
return mangled;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addStrings(node, keep) {
|
|
||||||
var out = {};
|
|
||||||
try {
|
|
||||||
(function walk(node){
|
|
||||||
node.walk(new TreeWalker(function(node){
|
|
||||||
if (node instanceof AST_Sequence) {
|
|
||||||
walk(node.expressions[node.expressions.length - 1]);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (node instanceof AST_String) {
|
|
||||||
add(node.value, keep);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (node instanceof AST_Conditional) {
|
|
||||||
walk(node.consequent);
|
|
||||||
walk(node.alternative);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
throw out;
|
|
||||||
}));
|
|
||||||
})(node);
|
|
||||||
} catch(ex) {
|
|
||||||
if (ex !== out) throw ex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function mangleStrings(node) {
|
function mangleStrings(node) {
|
||||||
return node.transform(new TreeTransformer(function(node){
|
return node.transform(new TreeTransformer(function(node){
|
||||||
if (node instanceof AST_Sequence) {
|
if (node instanceof AST_Sequence) {
|
||||||
|
|||||||
147
lib/scope.js
147
lib/scope.js
@@ -79,7 +79,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);
|
||||||
@@ -87,6 +87,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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -206,6 +209,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);
|
||||||
|
|
||||||
@@ -222,6 +235,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
ref.reference(options);
|
ref.reference(options);
|
||||||
});
|
});
|
||||||
node.thedef = def;
|
node.thedef = def;
|
||||||
|
node.reference(options);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
@@ -348,7 +362,8 @@ AST_Function.DEFMETHOD("next_mangled", function(options, def){
|
|||||||
});
|
});
|
||||||
|
|
||||||
AST_Symbol.DEFMETHOD("unmangleable", function(options){
|
AST_Symbol.DEFMETHOD("unmangleable", function(options){
|
||||||
return this.definition().unmangleable(options);
|
var def = this.definition();
|
||||||
|
return !def || def.unmangleable(options);
|
||||||
});
|
});
|
||||||
|
|
||||||
// labels are always mangleable
|
// labels are always mangleable
|
||||||
@@ -359,14 +374,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;
|
||||||
});
|
});
|
||||||
@@ -447,103 +454,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_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" + node.key);
|
|
||||||
else if (node instanceof AST_ObjectGetter)
|
|
||||||
base54.consider("get" + node.key);
|
|
||||||
else if (node instanceof AST_ObjectKeyVal)
|
|
||||||
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_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_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];
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
function compare(a, b) {
|
||||||
|
return frequency[b] - frequency[a];
|
||||||
|
}
|
||||||
base54.sort = function() {
|
base54.sort = function() {
|
||||||
chars = mergeSort(chars, function(a, b){
|
chars = mergeSort(leading, compare).concat(mergeSort(digits, compare));
|
||||||
if (is_digit(a) && !is_digit(b)) return 1;
|
|
||||||
if (is_digit(b) && !is_digit(a)) return -1;
|
|
||||||
return frequency[b] - frequency[a];
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
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;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
10
package.json
10
package.json
@@ -4,7 +4,7 @@
|
|||||||
"homepage": "http://lisperator.net/uglifyjs",
|
"homepage": "http://lisperator.net/uglifyjs",
|
||||||
"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.1.3",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
},
|
},
|
||||||
@@ -29,13 +29,13 @@
|
|||||||
"LICENSE"
|
"LICENSE"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"commander": "~2.9.0",
|
"commander": "~2.11.0",
|
||||||
"source-map": "~0.5.1"
|
"source-map": "~0.5.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"acorn": "~5.0.3",
|
"acorn": "~5.1.1",
|
||||||
"mocha": "~2.3.4",
|
"mocha": "~3.5.1",
|
||||||
"semver": "~5.3.0"
|
"semver": "~5.4.1"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "node test/run-tests.js"
|
"test": "node test/run-tests.js"
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ ascii_only_true: {
|
|||||||
"\x20\x21\x22\x23 ... \x7d\x7e\x7f\x80\x81 ... \xfe\xff\u0fff\uffff";
|
"\x20\x21\x22\x23 ... \x7d\x7e\x7f\x80\x81 ... \xfe\xff\u0fff\uffff";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect_exact: 'function f(){return"\\x000\\x001\\x007\\08\\0"+"\\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\b\\t\\n\\v\\f\\r\\x0e\\x0f"+"\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f"+\' !"# ... }~\\x7f\\x80\\x81 ... \\xfe\\xff\\u0fff\\uffff\'}'
|
expect_exact: 'function f(){return"\\x000\\x001\\x007\\x008\\0"+"\\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\b\\t\\n\\v\\f\\r\\x0e\\x0f"+"\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f"+\' !"# ... }~\\x7f\\x80\\x81 ... \\xfe\\xff\\u0fff\\uffff\'}'
|
||||||
}
|
}
|
||||||
|
|
||||||
ascii_only_false: {
|
ascii_only_false: {
|
||||||
@@ -31,5 +31,5 @@ ascii_only_false: {
|
|||||||
"\x20\x21\x22\x23 ... \x7d\x7e\x7f\x80\x81 ... \xfe\xff\u0fff\uffff";
|
"\x20\x21\x22\x23 ... \x7d\x7e\x7f\x80\x81 ... \xfe\xff\u0fff\uffff";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect_exact: 'function f(){return"\\x000\\x001\\x007\\08\\0"+"\\0\x01\x02\x03\x04\x05\x06\x07\\b\\t\\n\\v\\f\\r\x0e\x0f"+"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"+\' !"# ... }~\x7f\x80\x81 ... \xfe\xff\u0fff\uffff\'}'
|
expect_exact: 'function f(){return"\\x000\\x001\\x007\\x008\\0"+"\\0\x01\x02\x03\x04\x05\x06\x07\\b\\t\\n\\v\\f\\r\x0e\x0f"+"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"+\' !"# ... }~\x7f\x80\x81 ... \xfe\xff\u0fff\uffff\'}'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,3 +104,65 @@ asm_mixed: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
asm_toplevel: {
|
||||||
|
options = {}
|
||||||
|
input: {
|
||||||
|
"use asm";
|
||||||
|
0.0;
|
||||||
|
function f() {
|
||||||
|
0.0;
|
||||||
|
(function(){
|
||||||
|
0.0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
expect_exact: '"use asm";0.0;function f(){0.0;(function(){0.0})}0.0;'
|
||||||
|
}
|
||||||
|
|
||||||
|
asm_function_expression: {
|
||||||
|
options = {}
|
||||||
|
input: {
|
||||||
|
0.0;
|
||||||
|
var a = function() {
|
||||||
|
"use asm";
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
function f() {
|
||||||
|
0.0;
|
||||||
|
return function(){
|
||||||
|
"use asm";
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
expect_exact: '0;var a=function(){"use asm";0.0};function f(){0;return function(){"use asm";0.0};0}0;'
|
||||||
|
}
|
||||||
|
|
||||||
|
asm_nested_functions: {
|
||||||
|
options = {}
|
||||||
|
input: {
|
||||||
|
0.0;
|
||||||
|
function a() {
|
||||||
|
"use asm";
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
0.0;
|
||||||
|
function b() {
|
||||||
|
0.0;
|
||||||
|
function c(){
|
||||||
|
"use asm";
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
0.0;
|
||||||
|
function d(){
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
expect_exact: '0;function a(){"use asm";0.0}0;function b(){0;function c(){"use asm";0.0}0;function d(){0}0}0;'
|
||||||
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -1978,10 +1978,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"
|
||||||
}
|
}
|
||||||
@@ -2186,3 +2186,338 @@ compound_assignment: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "4"
|
expect_stdout: "4"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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"
|
||||||
|
}
|
||||||
|
|
||||||
|
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"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2298: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function() {
|
||||||
|
function f() {
|
||||||
|
var a = undefined;
|
||||||
|
var undefined = a++;
|
||||||
|
try {
|
||||||
|
!function g(b) {
|
||||||
|
b[1] = "foo";
|
||||||
|
}();
|
||||||
|
console.log("FAIL");
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function() {
|
||||||
|
(function() {
|
||||||
|
var a = undefined;
|
||||||
|
var undefined = a++;
|
||||||
|
try {
|
||||||
|
!function(b) {
|
||||||
|
(void 0)[1] = "foo";
|
||||||
|
}();
|
||||||
|
console.log("FAIL");
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2313_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0, b = 0;
|
||||||
|
var foo = {
|
||||||
|
get c() {
|
||||||
|
a++;
|
||||||
|
return 42;
|
||||||
|
},
|
||||||
|
set c(c) {
|
||||||
|
b++;
|
||||||
|
},
|
||||||
|
d: function() {
|
||||||
|
this.c++;
|
||||||
|
if (this.c) console.log(a, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foo.d();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0, b = 0;
|
||||||
|
var foo = {
|
||||||
|
get c() {
|
||||||
|
a++;
|
||||||
|
return 42;
|
||||||
|
},
|
||||||
|
set c(c) {
|
||||||
|
b++;
|
||||||
|
},
|
||||||
|
d: function() {
|
||||||
|
this.c++;
|
||||||
|
this.c && console.log(a, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foo.d();
|
||||||
|
}
|
||||||
|
expect_stdout: "2 1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2313_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var c = 0;
|
||||||
|
!function a() {
|
||||||
|
a && c++;
|
||||||
|
var a = 0;
|
||||||
|
a && c++;
|
||||||
|
}();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c = 0;
|
||||||
|
!function a() {
|
||||||
|
a && c++;
|
||||||
|
var a = 0;
|
||||||
|
a && c++;
|
||||||
|
}();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2319_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a) {
|
||||||
|
return a;
|
||||||
|
}(!function() {
|
||||||
|
return this;
|
||||||
|
}()));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a) {
|
||||||
|
return !function() {
|
||||||
|
return this;
|
||||||
|
}();
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "false"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2319_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a) {
|
||||||
|
"use strict";
|
||||||
|
return a;
|
||||||
|
}(!function() {
|
||||||
|
return this;
|
||||||
|
}()));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a) {
|
||||||
|
"use strict";
|
||||||
|
return a;
|
||||||
|
}(!function() {
|
||||||
|
return this;
|
||||||
|
}()));
|
||||||
|
}
|
||||||
|
expect_stdout: "false"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2319_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
console.log(function(a) {
|
||||||
|
return a;
|
||||||
|
}(!function() {
|
||||||
|
return this;
|
||||||
|
}()));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
console.log(function(a) {
|
||||||
|
return !function() {
|
||||||
|
return this;
|
||||||
|
}();
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "true"
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ concat_1: {
|
|||||||
var c = 1 + x() + 2 + "boo";
|
var c = 1 + x() + 2 + "boo";
|
||||||
var d = 1 + x() + 2 + 3 + "boo";
|
var d = 1 + x() + 2 + 3 + "boo";
|
||||||
var e = 1 + x() + 2 + "X3boo";
|
var e = 1 + x() + 2 + "X3boo";
|
||||||
var f = "\x00360\08\0";
|
var f = "\x00360\x008\0";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -230,3 +230,186 @@ accessor: {
|
|||||||
}
|
}
|
||||||
expect: {}
|
expect: {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2233_1: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
side_effects: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
Array.isArray;
|
||||||
|
Boolean;
|
||||||
|
console.log;
|
||||||
|
Date;
|
||||||
|
decodeURI;
|
||||||
|
decodeURIComponent;
|
||||||
|
encodeURI;
|
||||||
|
encodeURIComponent;
|
||||||
|
Error.name;
|
||||||
|
escape;
|
||||||
|
eval;
|
||||||
|
EvalError;
|
||||||
|
Function.length;
|
||||||
|
isFinite;
|
||||||
|
isNaN;
|
||||||
|
JSON;
|
||||||
|
Math.random;
|
||||||
|
Number.isNaN;
|
||||||
|
parseFloat;
|
||||||
|
parseInt;
|
||||||
|
RegExp;
|
||||||
|
Object.defineProperty;
|
||||||
|
String.fromCharCode;
|
||||||
|
RangeError;
|
||||||
|
ReferenceError;
|
||||||
|
SyntaxError;
|
||||||
|
TypeError;
|
||||||
|
unescape;
|
||||||
|
URIError;
|
||||||
|
}
|
||||||
|
expect: {}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
global_timeout_and_interval_symbols: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
side_effects: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
// These global symbols do not exist in the test sandbox
|
||||||
|
// and must be tested separately.
|
||||||
|
clearInterval;
|
||||||
|
clearTimeout;
|
||||||
|
setInterval;
|
||||||
|
setTimeout;
|
||||||
|
}
|
||||||
|
expect: {}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
global_fns: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
Boolean(1, 2);
|
||||||
|
decodeURI(1, 2);
|
||||||
|
decodeURIComponent(1, 2);
|
||||||
|
Date(1, 2);
|
||||||
|
encodeURI(1, 2);
|
||||||
|
encodeURIComponent(1, 2);
|
||||||
|
Error(1, 2);
|
||||||
|
escape(1, 2);
|
||||||
|
EvalError(1, 2);
|
||||||
|
isFinite(1, 2);
|
||||||
|
isNaN(1, 2);
|
||||||
|
Number(1, 2);
|
||||||
|
Object(1, 2);
|
||||||
|
parseFloat(1, 2);
|
||||||
|
parseInt(1, 2);
|
||||||
|
RangeError(1, 2);
|
||||||
|
ReferenceError(1, 2);
|
||||||
|
String(1, 2);
|
||||||
|
SyntaxError(1, 2);
|
||||||
|
TypeError(1, 2);
|
||||||
|
unescape(1, 2);
|
||||||
|
URIError(1, 2);
|
||||||
|
try {
|
||||||
|
Function(1, 2);
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e.name);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
RegExp(1, 2);
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e.name);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Array(NaN);
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
Function(1, 2);
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e.name);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
RegExp(1, 2);
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e.name);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Array(NaN);
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"SyntaxError",
|
||||||
|
"SyntaxError",
|
||||||
|
"RangeError",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
@@ -1090,6 +1090,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;
|
||||||
@@ -1099,12 +1100,164 @@ var_catch_toplevel: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
!function() {
|
!function() {
|
||||||
a--;
|
|
||||||
try {
|
try {
|
||||||
a++;
|
x();
|
||||||
} catch(a) {
|
} catch(a) {
|
||||||
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_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"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2288: {
|
||||||
|
options = {
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
beautify: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function foo(o) {
|
||||||
|
for (var j = o.a, i = 0; i < 0; i++);
|
||||||
|
for (var i = 0; i < 0; i++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function foo(o) {
|
||||||
|
o.a;
|
||||||
|
for (i = 0; i < 0; i++);
|
||||||
|
for (var i = 0; i < 0; i++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -250,22 +250,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
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -274,22 +278,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
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -298,21 +306,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
|
||||||
);
|
);
|
||||||
@@ -322,22 +334,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
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -386,9 +402,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
|
||||||
@@ -636,8 +652,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)();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1069,3 +1085,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
|
||||||
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -88,3 +88,24 @@ sequences_funs: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2295: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
hoist_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function foo(o) {
|
||||||
|
var a = o.a;
|
||||||
|
if (a) return a;
|
||||||
|
var a = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function foo(o) {
|
||||||
|
var a = o.a;
|
||||||
|
if (a) return a;
|
||||||
|
a = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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]",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,6 +96,13 @@ pure_function_calls_toplevel: {
|
|||||||
})();
|
})();
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
// pure top-level calls will be dropped regardless of the leading comments position
|
||||||
|
var MyClass = /*#__PURE__*//*@class*/(function(){
|
||||||
|
function MyClass() {}
|
||||||
|
MyClass.prototype.method = function() {};
|
||||||
|
return MyClass;
|
||||||
|
})();
|
||||||
|
|
||||||
// comment #__PURE__ comment
|
// comment #__PURE__ comment
|
||||||
bar(), baz(), quux();
|
bar(), baz(), quux();
|
||||||
a.b(), /* @__PURE__ */ c.d.e(), f.g();
|
a.b(), /* @__PURE__ */ c.d.e(), f.g();
|
||||||
@@ -110,10 +117,12 @@ pure_function_calls_toplevel: {
|
|||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:92,37]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:92,37]",
|
||||||
"WARN: Dropping unused variable iife2 [test/compress/issue-1261.js:92,16]",
|
"WARN: Dropping unused variable iife2 [test/compress/issue-1261.js:92,16]",
|
||||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:90,8]",
|
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:90,8]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:100,8]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:107,8]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:101,31]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:108,31]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:84,33]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:84,33]",
|
||||||
"WARN: Dropping unused variable iife1 [test/compress/issue-1261.js:84,12]",
|
"WARN: Dropping unused variable iife1 [test/compress/issue-1261.js:84,12]",
|
||||||
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:100,45]",
|
||||||
|
"WARN: Dropping unused variable MyClass [test/compress/issue-1261.js:100,12]",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,29 +157,29 @@ should_warn: {
|
|||||||
baz();
|
baz();
|
||||||
}
|
}
|
||||||
expect_warnings: [
|
expect_warnings: [
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:128,61]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:137,61]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:128,23]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:137,23]",
|
||||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:128,23]",
|
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:137,23]",
|
||||||
"WARN: Boolean || always true [test/compress/issue-1261.js:129,23]",
|
"WARN: Boolean || always true [test/compress/issue-1261.js:138,23]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:129,23]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:138,23]",
|
||||||
"WARN: Condition always true [test/compress/issue-1261.js:129,23]",
|
"WARN: Condition always true [test/compress/issue-1261.js:138,23]",
|
||||||
"WARN: Condition left of || always true [test/compress/issue-1261.js:130,8]",
|
"WARN: Condition left of || always true [test/compress/issue-1261.js:139,8]",
|
||||||
"WARN: Condition always true [test/compress/issue-1261.js:130,8]",
|
"WARN: Condition always true [test/compress/issue-1261.js:139,8]",
|
||||||
"WARN: Boolean && always false [test/compress/issue-1261.js:131,23]",
|
"WARN: Boolean && always false [test/compress/issue-1261.js:140,23]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:131,23]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:140,23]",
|
||||||
"WARN: Condition always false [test/compress/issue-1261.js:131,23]",
|
"WARN: Condition always false [test/compress/issue-1261.js:140,23]",
|
||||||
"WARN: Condition left of && always false [test/compress/issue-1261.js:132,8]",
|
"WARN: Condition left of && always false [test/compress/issue-1261.js:141,8]",
|
||||||
"WARN: Condition always false [test/compress/issue-1261.js:132,8]",
|
"WARN: Condition always false [test/compress/issue-1261.js:141,8]",
|
||||||
"WARN: + in boolean context always true [test/compress/issue-1261.js:133,23]",
|
"WARN: + in boolean context always true [test/compress/issue-1261.js:142,23]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:133,23]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:142,23]",
|
||||||
"WARN: Condition always true [test/compress/issue-1261.js:133,23]",
|
"WARN: Condition always true [test/compress/issue-1261.js:142,23]",
|
||||||
"WARN: + in boolean context always true [test/compress/issue-1261.js:134,8]",
|
"WARN: + in boolean context always true [test/compress/issue-1261.js:143,8]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:134,31]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:143,31]",
|
||||||
"WARN: Condition always true [test/compress/issue-1261.js:134,8]",
|
"WARN: Condition always true [test/compress/issue-1261.js:143,8]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:135,23]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:144,23]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:136,24]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:145,24]",
|
||||||
"WARN: Condition always true [test/compress/issue-1261.js:136,8]",
|
"WARN: Condition always true [test/compress/issue-1261.js:145,8]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:137,31]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:146,31]",
|
||||||
"WARN: Condition always false [test/compress/issue-1261.js:137,8]",
|
"WARN: Condition always false [test/compress/issue-1261.js:146,8]",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
issue_1321_no_debug: {
|
issue_1321_no_debug: {
|
||||||
mangle_props = {
|
mangle = {
|
||||||
keep_quoted: true
|
properties: {
|
||||||
|
keep_quoted: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var x = {};
|
var x = {};
|
||||||
@@ -10,17 +12,19 @@ issue_1321_no_debug: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var x = {};
|
var x = {};
|
||||||
x.b = 1;
|
x.x = 1;
|
||||||
x["a"] = 2 * x.b;
|
x["a"] = 2 * x.x;
|
||||||
console.log(x.b, x["a"]);
|
console.log(x.x, x["a"]);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_1321_debug: {
|
issue_1321_debug: {
|
||||||
mangle_props = {
|
mangle = {
|
||||||
keep_quoted: true,
|
properties: {
|
||||||
debug: ""
|
debug: "",
|
||||||
|
keep_quoted: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var x = {};
|
var x = {};
|
||||||
@@ -30,16 +34,18 @@ issue_1321_debug: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var x = {};
|
var x = {};
|
||||||
x.a = 1;
|
x.x = 1;
|
||||||
x["_$foo$_"] = 2 * x.a;
|
x["_$foo$_"] = 2 * x.x;
|
||||||
console.log(x.a, x["_$foo$_"]);
|
console.log(x.x, x["_$foo$_"]);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_1321_with_quoted: {
|
issue_1321_with_quoted: {
|
||||||
mangle_props = {
|
mangle = {
|
||||||
keep_quoted: false
|
properties: {
|
||||||
|
keep_quoted: false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var x = {};
|
var x = {};
|
||||||
@@ -49,9 +55,9 @@ issue_1321_with_quoted: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var x = {};
|
var x = {};
|
||||||
x.a = 1;
|
x.x = 1;
|
||||||
x["b"] = 2 * x.a;
|
x["o"] = 2 * x.x;
|
||||||
console.log(x.a, x["b"]);
|
console.log(x.x, x["o"]);
|
||||||
}
|
}
|
||||||
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: {
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
mangle_props: {
|
mangle_props: {
|
||||||
mangle_props = {}
|
mangle = {
|
||||||
|
properties: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
var obj = {
|
var obj = {
|
||||||
undefined: 1,
|
undefined: 1,
|
||||||
@@ -54,10 +56,12 @@ mangle_props: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
numeric_literal: {
|
numeric_literal: {
|
||||||
|
mangle = {
|
||||||
|
properties: true,
|
||||||
|
}
|
||||||
beautify = {
|
beautify = {
|
||||||
beautify: true,
|
beautify: true,
|
||||||
}
|
}
|
||||||
mangle_props = {}
|
|
||||||
input: {
|
input: {
|
||||||
var obj = {
|
var obj = {
|
||||||
0: 0,
|
0: 0,
|
||||||
@@ -82,7 +86,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 +96,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"]);',
|
||||||
]
|
]
|
||||||
@@ -105,7 +109,9 @@ numeric_literal: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
identifier: {
|
identifier: {
|
||||||
mangle_props = {}
|
mangle = {
|
||||||
|
properties: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
var obj = {
|
var obj = {
|
||||||
abstract: 1,
|
abstract: 1,
|
||||||
@@ -173,32 +179,32 @@ identifier: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var obj = {
|
var obj = {
|
||||||
a: 1,
|
e: 1,
|
||||||
b: 2,
|
t: 2,
|
||||||
c: 3,
|
n: 3,
|
||||||
d: 4,
|
a: 4,
|
||||||
e: 5,
|
i: 5,
|
||||||
f: 6,
|
o: 6,
|
||||||
g: 7,
|
r: 7,
|
||||||
h: 8,
|
l: 8,
|
||||||
i: 9,
|
s: 9,
|
||||||
j: 10,
|
c: 10,
|
||||||
k: 11,
|
f: 11,
|
||||||
l: 12,
|
u: 12,
|
||||||
m: 13,
|
d: 13,
|
||||||
n: 14,
|
h: 14,
|
||||||
o: 15,
|
p: 15,
|
||||||
p: 16,
|
b: 16,
|
||||||
q: 17,
|
v: 17,
|
||||||
r: 18,
|
w: 18,
|
||||||
s: 19,
|
y: 19,
|
||||||
t: 20,
|
g: 20,
|
||||||
u: 21,
|
m: 21,
|
||||||
v: 22,
|
k: 22,
|
||||||
w: 23,
|
x: 23,
|
||||||
x: 24,
|
j: 24,
|
||||||
y: 25,
|
z: 25,
|
||||||
z: 26,
|
q: 26,
|
||||||
A: 27,
|
A: 27,
|
||||||
B: 28,
|
B: 28,
|
||||||
C: 29,
|
C: 29,
|
||||||
@@ -229,11 +235,11 @@ identifier: {
|
|||||||
Z: 54,
|
Z: 54,
|
||||||
$: 55,
|
$: 55,
|
||||||
_: 56,
|
_: 56,
|
||||||
aa: 57,
|
ee: 57,
|
||||||
ba: 58,
|
te: 58,
|
||||||
ca: 59,
|
ne: 59,
|
||||||
da: 60,
|
ae: 60,
|
||||||
ea: 61,
|
ie: 61,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,45 @@
|
|||||||
dont_reuse_prop: {
|
dont_reuse_prop: {
|
||||||
mangle_props = {
|
mangle = {
|
||||||
regex: /asd/
|
properties: {
|
||||||
};
|
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 = {
|
||||||
regex: /asd/
|
properties: {
|
||||||
};
|
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"
|
||||||
|
}
|
||||||
|
|||||||
@@ -436,3 +436,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;);'
|
||||||
|
}
|
||||||
|
|||||||
@@ -82,3 +82,19 @@ new_with_unary_prefix: {
|
|||||||
}
|
}
|
||||||
expect_exact: 'var bar=(+new Date).toString(32);';
|
expect_exact: 'var bar=(+new Date).toString(32);';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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"
|
||||||
|
}
|
||||||
|
|||||||
@@ -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";
|
||||||
@@ -124,9 +128,11 @@ evaluate_string_length: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mangle_properties: {
|
mangle_properties: {
|
||||||
mangle_props = {
|
mangle = {
|
||||||
keep_quoted: false
|
properties: {
|
||||||
};
|
keep_quoted: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
a["foo"] = "bar";
|
a["foo"] = "bar";
|
||||||
a.color = "red";
|
a.color = "red";
|
||||||
@@ -137,9 +143,9 @@ mangle_properties: {
|
|||||||
expect: {
|
expect: {
|
||||||
a["a"] = "bar";
|
a["a"] = "bar";
|
||||||
a.b = "red";
|
a.b = "red";
|
||||||
x = {c: 10};
|
x = {o: 10};
|
||||||
a.d(x.c, a.a);
|
a.r(x.o, a.a);
|
||||||
a['d']({b: "blue", a: "baz"});
|
a['r']({b: "blue", a: "baz"});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,8 +153,10 @@ mangle_unquoted_properties: {
|
|||||||
options = {
|
options = {
|
||||||
properties: false
|
properties: false
|
||||||
}
|
}
|
||||||
mangle_props = {
|
mangle = {
|
||||||
keep_quoted: true
|
properties: {
|
||||||
|
keep_quoted: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
beautify = {
|
beautify = {
|
||||||
beautify: false,
|
beautify: false,
|
||||||
@@ -177,24 +185,26 @@ mangle_unquoted_properties: {
|
|||||||
function f1() {
|
function f1() {
|
||||||
a["foo"] = "bar";
|
a["foo"] = "bar";
|
||||||
a.color = "red";
|
a.color = "red";
|
||||||
a.b = 2;
|
a.r = 2;
|
||||||
x = {"bar": 10, c: 7};
|
x = {"bar": 10, b: 7};
|
||||||
a.c = 9;
|
a.b = 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, b: 7};
|
||||||
a.c = 9;
|
a.b = 9;
|
||||||
a.b = 3;
|
a.r = 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mangle_debug: {
|
mangle_debug: {
|
||||||
mangle_props = {
|
mangle = {
|
||||||
debug: ""
|
properties: {
|
||||||
};
|
debug: "",
|
||||||
|
},
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
a.foo = "bar";
|
a.foo = "bar";
|
||||||
x = { baz: "ban" };
|
x = { baz: "ban" };
|
||||||
@@ -206,9 +216,11 @@ mangle_debug: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mangle_debug_true: {
|
mangle_debug_true: {
|
||||||
mangle_props = {
|
mangle = {
|
||||||
debug: true
|
properties: {
|
||||||
};
|
debug: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
a.foo = "bar";
|
a.foo = "bar";
|
||||||
x = { baz: "ban" };
|
x = { baz: "ban" };
|
||||||
@@ -220,9 +232,11 @@ mangle_debug_true: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mangle_debug_suffix: {
|
mangle_debug_suffix: {
|
||||||
mangle_props = {
|
mangle = {
|
||||||
debug: "XYZ"
|
properties: {
|
||||||
};
|
debug: "XYZ",
|
||||||
|
},
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
a.foo = "bar";
|
a.foo = "bar";
|
||||||
x = { baz: "ban" };
|
x = { baz: "ban" };
|
||||||
@@ -237,10 +251,12 @@ mangle_debug_suffix_keep_quoted: {
|
|||||||
options = {
|
options = {
|
||||||
properties: false
|
properties: false
|
||||||
}
|
}
|
||||||
mangle_props = {
|
mangle = {
|
||||||
keep_quoted: true,
|
properties: {
|
||||||
debug: "XYZ",
|
debug: "XYZ",
|
||||||
reserved: []
|
keep_quoted: true,
|
||||||
|
reserved: [],
|
||||||
|
},
|
||||||
}
|
}
|
||||||
beautify = {
|
beautify = {
|
||||||
beautify: false,
|
beautify: false,
|
||||||
@@ -657,3 +673,134 @@ 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_2256: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
properties: {
|
||||||
|
keep_quoted: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
({ "keep": 1 });
|
||||||
|
g.keep = g.change;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
g.keep = g.g;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -178,3 +178,424 @@ 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"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2313_1: {
|
||||||
|
options = {
|
||||||
|
cascade: true,
|
||||||
|
conditionals: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function x() {
|
||||||
|
console.log(1);
|
||||||
|
return {
|
||||||
|
y: function() {
|
||||||
|
console.log(2);
|
||||||
|
return {
|
||||||
|
z: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
x().y().z++;
|
||||||
|
if (x().y().z) {
|
||||||
|
console.log(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function x() {
|
||||||
|
return console.log(1), {
|
||||||
|
y: function() {
|
||||||
|
return console.log(2), {
|
||||||
|
z: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
x().y().z++,
|
||||||
|
x().y().z && console.log(3);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2313_2: {
|
||||||
|
options = {
|
||||||
|
cascade: true,
|
||||||
|
conditionals: true,
|
||||||
|
pure_getters: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function x() {
|
||||||
|
console.log(1);
|
||||||
|
return {
|
||||||
|
y: function() {
|
||||||
|
console.log(2);
|
||||||
|
return {
|
||||||
|
z: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
x().y().z++;
|
||||||
|
if (x().y().z) {
|
||||||
|
console.log(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function x() {
|
||||||
|
return console.log(1), {
|
||||||
|
y: function() {
|
||||||
|
return console.log(2), {
|
||||||
|
z: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
x().y().z++,
|
||||||
|
x().y().z && console.log(3);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2313_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function x() {
|
||||||
|
console.log(1);
|
||||||
|
return {
|
||||||
|
y: function() {
|
||||||
|
console.log(2);
|
||||||
|
return {
|
||||||
|
z: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
x().y().z++;
|
||||||
|
if (x().y().z) {
|
||||||
|
console.log(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function x() {
|
||||||
|
console.log(1);
|
||||||
|
return {
|
||||||
|
y: function() {
|
||||||
|
console.log(2);
|
||||||
|
return {
|
||||||
|
z: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
x().y().z++;
|
||||||
|
x().y().z && console.log(3);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2313_4: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
pure_getters: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function x() {
|
||||||
|
console.log(1);
|
||||||
|
return {
|
||||||
|
y: function() {
|
||||||
|
console.log(2);
|
||||||
|
return {
|
||||||
|
z: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
x().y().z++;
|
||||||
|
if (x().y().z) {
|
||||||
|
console.log(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function x() {
|
||||||
|
console.log(1);
|
||||||
|
return {
|
||||||
|
y: function() {
|
||||||
|
console.log(2);
|
||||||
|
return {
|
||||||
|
z: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
x().y().z++;
|
||||||
|
x().y().z && console.log(3);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2313_5: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
x().y++;
|
||||||
|
x().y;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
x().y++;
|
||||||
|
x().y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2313_6: {
|
||||||
|
options = {
|
||||||
|
pure_getters: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
x().y++;
|
||||||
|
x().y;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
x().y++;
|
||||||
|
x();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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: {
|
||||||
@@ -2547,7 +2549,7 @@ issue_1922_2: {
|
|||||||
expect_stdout: "1"
|
expect_stdout: "1"
|
||||||
}
|
}
|
||||||
|
|
||||||
accessor: {
|
accessor_1: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
@@ -2575,3 +2577,55 @@ accessor: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "1 1"
|
expect_stdout: "1 1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
accessor_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var A = 1;
|
||||||
|
var B = {
|
||||||
|
get c() {
|
||||||
|
console.log(A);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
B.c;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
({
|
||||||
|
get c() {
|
||||||
|
console.log(1);
|
||||||
|
}
|
||||||
|
}).c;
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
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,139 @@ 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"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2254_1: {
|
||||||
|
mangle = {
|
||||||
|
ie8: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"eeeeee";
|
||||||
|
try {
|
||||||
|
console.log(f("PASS"));
|
||||||
|
} catch (e) {}
|
||||||
|
function f(s) {
|
||||||
|
try {
|
||||||
|
throw "FAIL";
|
||||||
|
} catch (e) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"eeeeee";
|
||||||
|
try {
|
||||||
|
console.log(f("PASS"));
|
||||||
|
} catch (e) {}
|
||||||
|
function f(e) {
|
||||||
|
try {
|
||||||
|
throw "FAIL";
|
||||||
|
} catch (t) {
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2254_2: {
|
||||||
|
mangle = {
|
||||||
|
ie8: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"eeeeee";
|
||||||
|
try {
|
||||||
|
console.log(f("PASS"));
|
||||||
|
} catch (e) {}
|
||||||
|
function f(s) {
|
||||||
|
try {
|
||||||
|
throw "FAIL";
|
||||||
|
} catch (e) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"eeeeee";
|
||||||
|
try {
|
||||||
|
console.log(f("PASS"));
|
||||||
|
} catch (e) {}
|
||||||
|
function f(t) {
|
||||||
|
try {
|
||||||
|
throw "FAIL";
|
||||||
|
} catch (e) {
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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;);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -730,3 +739,44 @@ issue_2062: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "1"
|
expect_stdout: "1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2313: {
|
||||||
|
options = {
|
||||||
|
cascade: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0, b = 0;
|
||||||
|
var foo = {
|
||||||
|
get c() {
|
||||||
|
a++;
|
||||||
|
return 42;
|
||||||
|
},
|
||||||
|
set c(c) {
|
||||||
|
b++;
|
||||||
|
},
|
||||||
|
d: function() {
|
||||||
|
this.c++;
|
||||||
|
if (this.c) console.log(a, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foo.d();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0, b = 0;
|
||||||
|
var foo = {
|
||||||
|
get c() {
|
||||||
|
return a++, 42;
|
||||||
|
},
|
||||||
|
set c(c) {
|
||||||
|
b++;
|
||||||
|
},
|
||||||
|
d: function() {
|
||||||
|
if (this.c++, this.c) console.log(a, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foo.d();
|
||||||
|
}
|
||||||
|
expect_stdout: "2 1"
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,3 +15,43 @@ unicode_parse_variables: {
|
|||||||
var l০ = 3;
|
var l০ = 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2242_1: {
|
||||||
|
beautify = {
|
||||||
|
ascii_only: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log("\ud83d", "\ude00", "\ud83d\ude00", "\ud83d@\ude00");
|
||||||
|
}
|
||||||
|
expect_exact: 'console.log("\\ud83d","\\ude00","\ud83d\ude00","\\ud83d@\\ude00");'
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2242_2: {
|
||||||
|
beautify = {
|
||||||
|
ascii_only: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log("\ud83d", "\ude00", "\ud83d\ude00", "\ud83d@\ude00");
|
||||||
|
}
|
||||||
|
expect_exact: 'console.log("\\ud83d","\\ude00","\\ud83d\\ude00","\\ud83d@\\ude00");'
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2242_3: {
|
||||||
|
options = {
|
||||||
|
evaluate: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log("\ud83d" + "\ude00", "\ud83d" + "@" + "\ude00");
|
||||||
|
}
|
||||||
|
expect_exact: 'console.log("\\ud83d"+"\\ude00","\\ud83d"+"@"+"\\ude00");'
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2242_4: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log("\ud83d" + "\ude00", "\ud83d" + "@" + "\ude00");
|
||||||
|
}
|
||||||
|
expect_exact: 'console.log("\ud83d\ude00","\\ud83d@\\ude00");'
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ exports["defaults"] = defaults;
|
|||||||
exports["mangle_properties"] = mangle_properties;
|
exports["mangle_properties"] = mangle_properties;
|
||||||
exports["minify"] = minify;
|
exports["minify"] = minify;
|
||||||
exports["parse"] = parse;
|
exports["parse"] = parse;
|
||||||
|
exports["reserve_quoted_keys"] = reserve_quoted_keys;
|
||||||
exports["string_template"] = string_template;
|
exports["string_template"] = string_template;
|
||||||
exports["tokenizer"] = tokenizer;
|
exports["tokenizer"] = tokenizer;
|
||||||
exports["is_identifier"] = is_identifier;
|
exports["is_identifier"] = is_identifier;
|
||||||
|
|||||||
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]);
|
||||||
|
}
|
||||||
10
test/input/issue-2310/input.js
Normal file
10
test/input/issue-2310/input.js
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
function foo() {
|
||||||
|
return function() {
|
||||||
|
console.log("PASS");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
var f = foo();
|
||||||
|
f();
|
||||||
|
})();
|
||||||
@@ -63,7 +63,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 +192,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");
|
||||||
@@ -518,6 +518,36 @@ describe("bin/uglifyjs", function () {
|
|||||||
done();
|
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,
|
||||||
@@ -543,6 +573,25 @@ describe("bin/uglifyjs", function () {
|
|||||||
return JSON.stringify(map).replace(/"/g, '\\"');
|
return JSON.stringify(map).replace(/"/g, '\\"');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
it("Should include function calls in source map", function(done) {
|
||||||
|
var command = [
|
||||||
|
uglifyjscmd,
|
||||||
|
"test/input/issue-2310/input.js",
|
||||||
|
"-c",
|
||||||
|
"--source-map", "url=inline",
|
||||||
|
].join(" ");
|
||||||
|
|
||||||
|
exec(command, function(err, stdout, stderr) {
|
||||||
|
if (err) throw err;
|
||||||
|
|
||||||
|
assert.strictEqual(stdout, [
|
||||||
|
'function foo(){return function(){console.log("PASS")}}foo()();',
|
||||||
|
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMjMxMC9pbnB1dC5qcyJdLCJuYW1lcyI6WyJmb28iLCJjb25zb2xlIiwibG9nIiwiZiJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsTUFDTCxPQUFPLFdBQ0hDLFFBQVFDLElBQUksU0FLUkYsS0FDUkcifQ==",
|
||||||
|
""
|
||||||
|
].join("\n"));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
it("Should dump AST as JSON", function(done) {
|
it("Should dump AST as JSON", function(done) {
|
||||||
var command = uglifyjscmd + " test/input/global_defs/simple.js -mco ast";
|
var command = uglifyjscmd + " test/input/global_defs/simple.js -mco ast";
|
||||||
exec(command, function (err, stdout) {
|
exec(command, function (err, stdout) {
|
||||||
@@ -563,8 +612,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;
|
||||||
@@ -573,8 +622,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;
|
||||||
@@ -583,4 +632,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();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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,64 @@ 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));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not parse invalid use of reserved words", function() {
|
||||||
|
assert.strictEqual(Uglify.minify("function enum(){}").error, undefined);
|
||||||
|
assert.strictEqual(Uglify.minify("function static(){}").error, undefined);
|
||||||
|
assert.strictEqual(Uglify.minify("function this(){}").error.message, "Unexpected token: name (this)");
|
||||||
|
});
|
||||||
|
|
||||||
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};';
|
||||||
@@ -71,6 +130,17 @@ describe("minify", function() {
|
|||||||
assert.strictEqual(result.code,
|
assert.strictEqual(result.code,
|
||||||
'a["foo"]="bar",a.a="red",x={"bar":10};');
|
'a["foo"]="bar",a.a="red",x={"bar":10};');
|
||||||
});
|
});
|
||||||
|
it("Should not mangle quoted property within dead code", function() {
|
||||||
|
var result = Uglify.minify('({ "keep": 1 }); g.keep = g.change;', {
|
||||||
|
mangle: {
|
||||||
|
properties: {
|
||||||
|
keep_quoted: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
assert.strictEqual(result.code, "g.keep=g.g;");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("inSourceMap", function() {
|
describe("inSourceMap", function() {
|
||||||
@@ -212,7 +282,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 });
|
||||||
|
|||||||
@@ -61,9 +61,9 @@ describe("String literals", function() {
|
|||||||
var tests = [
|
var tests = [
|
||||||
['"\\76";', ';">";'],
|
['"\\76";', ';">";'],
|
||||||
['"\\0"', '"\\0";'],
|
['"\\0"', '"\\0";'],
|
||||||
['"\\08"', '"\\08";'],
|
['"\\08"', '"\\x008";'],
|
||||||
['"\\008"', '"\\08";'],
|
['"\\008"', '"\\x008";'],
|
||||||
['"\\0008"', '"\\08";'],
|
['"\\0008"', '"\\x008";'],
|
||||||
['"use strict" === "use strict";\n"\\76";', '"use strict"==="use strict";">";'],
|
['"use strict" === "use strict";\n"\\76";', '"use strict"==="use strict";">";'],
|
||||||
['"use\\\n strict";\n"\\07";', ';"use strict";"\07";']
|
['"use\\\n strict";\n"\\07";', ';"use strict";"\07";']
|
||||||
];
|
];
|
||||||
@@ -75,7 +75,44 @@ describe("String literals", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Should not throw error when digit is 8 or 9", function() {
|
it("Should not throw error when digit is 8 or 9", function() {
|
||||||
assert.equal(UglifyJS.parse('"use strict";"\\08"').print_to_string(), '"use strict";"\\08";');
|
assert.equal(UglifyJS.parse('"use strict";"\\08"').print_to_string(), '"use strict";"\\x008";');
|
||||||
assert.equal(UglifyJS.parse('"use strict";"\\09"').print_to_string(), '"use strict";"\\09";');
|
assert.equal(UglifyJS.parse('"use strict";"\\09"').print_to_string(), '"use strict";"\\x009";');
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should not unescape unpaired surrogates", function() {
|
||||||
|
var code = [];
|
||||||
|
for (var i = 0; i <= 0xF; i++) {
|
||||||
|
code.push("\\u000" + i.toString(16));
|
||||||
|
}
|
||||||
|
for (;i <= 0xFF; i++) {
|
||||||
|
code.push("\\u00" + i.toString(16));
|
||||||
|
}
|
||||||
|
for (;i <= 0xFFF; i++) {
|
||||||
|
code.push("\\u0" + i.toString(16));
|
||||||
|
}
|
||||||
|
for (; i <= 0xFFFF; i++) {
|
||||||
|
code.push("\\u" + i.toString(16));
|
||||||
|
}
|
||||||
|
code = '"' + code.join() + '"';
|
||||||
|
var normal = UglifyJS.minify(code, {
|
||||||
|
compress: false,
|
||||||
|
mangle: false,
|
||||||
|
output: {
|
||||||
|
ascii_only: false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (normal.error) throw normal.error;
|
||||||
|
assert.ok(code.length > normal.code.length);
|
||||||
|
assert.strictEqual(eval(code), eval(normal.code));
|
||||||
|
var ascii = UglifyJS.minify(code, {
|
||||||
|
compress: false,
|
||||||
|
mangle: false,
|
||||||
|
output: {
|
||||||
|
ascii_only: false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (ascii.error) throw ascii.error;
|
||||||
|
assert.ok(code.length > ascii.code.length);
|
||||||
|
assert.strictEqual(eval(code), eval(ascii.code));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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
|
||||||
});
|
});
|
||||||
@@ -115,12 +111,22 @@ function run_compress_tests() {
|
|||||||
};
|
};
|
||||||
if (!options.warnings) options.warnings = true;
|
if (!options.warnings) options.warnings = true;
|
||||||
}
|
}
|
||||||
|
if (test.mangle && test.mangle.properties && test.mangle.properties.keep_quoted) {
|
||||||
|
var quoted_props = test.mangle.properties.reserved;
|
||||||
|
if (!Array.isArray(quoted_props)) quoted_props = [];
|
||||||
|
test.mangle.properties.reserved = quoted_props;
|
||||||
|
U.reserve_quoted_keys(input, quoted_props);
|
||||||
|
}
|
||||||
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) {
|
||||||
|
U.base54.reset();
|
||||||
output.compute_char_frequency(test.mangle);
|
output.compute_char_frequency(test.mangle);
|
||||||
output.mangle_names(test.mangle);
|
output.mangle_names(test.mangle);
|
||||||
|
if (test.mangle.properties) {
|
||||||
|
output = U.mangle_properties(output, test.mangle.properties);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
output = make_code(output, output_options);
|
output = make_code(output, output_options);
|
||||||
if (expect != output) {
|
if (expect != output) {
|
||||||
|
|||||||
Reference in New Issue
Block a user