Compare commits
119 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0cfbd79aa1 | ||
|
|
d66d86f20b | ||
|
|
905325d3e2 | ||
|
|
dea0cc0662 | ||
|
|
d69d8007d6 | ||
|
|
c0b8f2a16d | ||
|
|
cb0257dbbf | ||
|
|
9637f51b68 | ||
|
|
3026bd8975 | ||
|
|
78a44d5ab0 | ||
|
|
7e13c0db40 | ||
|
|
e6a2e9e4d0 | ||
|
|
e773f03927 | ||
|
|
b16380d669 | ||
|
|
334b07a3db | ||
|
|
3cc1527f00 | ||
|
|
525a61fb55 | ||
|
|
c3a002ff97 | ||
|
|
fad6766a90 | ||
|
|
aa664dea0a | ||
|
|
102f994b9d | ||
|
|
2a4c68be4f | ||
|
|
541e6011af | ||
|
|
6fa3fbeae8 | ||
|
|
4eb4cb656c | ||
|
|
193612ac67 | ||
|
|
95cfce68ea | ||
|
|
ec4202590d | ||
|
|
5e2cd07d6f | ||
|
|
06166df999 | ||
|
|
e2dc9cf091 | ||
|
|
069df27bf1 | ||
|
|
3e7873217c | ||
|
|
e21bab7ce6 | ||
|
|
ac9a168fba | ||
|
|
81b64549ce | ||
|
|
082e004b87 | ||
|
|
983e69128b | ||
|
|
b335912e86 | ||
|
|
cc07f3b806 | ||
|
|
07e4b64f3a | ||
|
|
d3ce2bc9e7 | ||
|
|
cff3bf4914 | ||
|
|
79cfac77bd | ||
|
|
224c14d49d | ||
|
|
7857354d85 | ||
|
|
b4aef753e7 | ||
|
|
424173d311 | ||
|
|
ec7cd1dcf7 | ||
|
|
7def684730 | ||
|
|
10f961c27b | ||
|
|
b483678ca7 | ||
|
|
cbbe6fad60 | ||
|
|
f96929c031 | ||
|
|
2b6657e967 | ||
|
|
7c0c92943f | ||
|
|
62a66dfff4 | ||
|
|
2cab348341 | ||
|
|
460218a3f8 | ||
|
|
e49416e4aa | ||
|
|
d4d7d99b70 | ||
|
|
6a696d0a7b | ||
|
|
1c9e13f47d | ||
|
|
b757450cd8 | ||
|
|
23ec484806 | ||
|
|
f1e1bb419a | ||
|
|
6a0af85c8b | ||
|
|
09269be974 | ||
|
|
bf832cde16 | ||
|
|
2972d58dbb | ||
|
|
2e22d38a02 | ||
|
|
ce27bcd69a | ||
|
|
9336cc8247 | ||
|
|
9809567dfc | ||
|
|
1ee8be8d91 | ||
|
|
8430c2f9f8 | ||
|
|
659c8a7632 | ||
|
|
3564b4f20d | ||
|
|
3505a3604a | ||
|
|
9b1bc6c014 | ||
|
|
9f23185f2b | ||
|
|
b82feb9302 | ||
|
|
7f2a591c7e | ||
|
|
afbcebddf6 | ||
|
|
484e484571 | ||
|
|
6f3f21233f | ||
|
|
a6873a3859 | ||
|
|
7a6d452b54 | ||
|
|
9b58b54e2d | ||
|
|
c598a12af9 | ||
|
|
cfe3a98ce5 | ||
|
|
14778e049b | ||
|
|
446fb0198b | ||
|
|
7d3cddf9d6 | ||
|
|
6dead95eb3 | ||
|
|
cc931b3ad8 | ||
|
|
d838b4b52e | ||
|
|
2f3bddbaca | ||
|
|
673b071637 | ||
|
|
da82fa59a7 | ||
|
|
333792352e | ||
|
|
e2ec270b04 | ||
|
|
ed7a0a454e | ||
|
|
d819559a01 | ||
|
|
8ca49155a8 | ||
|
|
b95e3338d9 | ||
|
|
e40a0ee9c6 | ||
|
|
cb62bd98d3 | ||
|
|
f30790b11b | ||
|
|
5205dbcbf4 | ||
|
|
3ff625de7e | ||
|
|
4832bc5d88 | ||
|
|
7f342cb3e3 | ||
|
|
05e7d34ed4 | ||
|
|
86607156e3 | ||
|
|
0fe259e9c5 | ||
|
|
8701a99a15 | ||
|
|
1476c78b53 | ||
|
|
cb6a92892f |
61
CONTRIBUTING.md
Normal file
61
CONTRIBUTING.md
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
Contributing
|
||||||
|
============
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
Every new feature and API change should be accompanied by a README additon.
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
All features and bugs should have tests that verify the fix. You can run all
|
||||||
|
tests using `npm test`.
|
||||||
|
|
||||||
|
The most common type of test are tests that verify input and output of the
|
||||||
|
Uglify transforms. These tests exist in `test/compress`. New tests can be added
|
||||||
|
either to an existing file or in a new file `issue-xxx.js`.
|
||||||
|
|
||||||
|
Tests that cannot be expressed as a simple AST can be found in `test/mocha`.
|
||||||
|
|
||||||
|
## Code style
|
||||||
|
|
||||||
|
- File encoding must be `UTF-8`.
|
||||||
|
- `LF` is always used as a line ending.
|
||||||
|
- Statements end with semicolons.
|
||||||
|
- Indentation uses 4 spaces, switch `case` 2 spaces.
|
||||||
|
- Identifiers use `snake_case`.
|
||||||
|
- Strings use double quotes (`"`).
|
||||||
|
- Use a trailing comma for multiline array and object literals to minimize diffs.
|
||||||
|
- The Uglify code only uses ES5, even in the `harmony` branch.
|
||||||
|
- Line length should be at most 80 cols, except when it is easier to read a
|
||||||
|
longer line.
|
||||||
|
- If both sides of a comparison are of the same type, `==` and `!=` are used.
|
||||||
|
- Multiline conditions place `&&` and `||` first on the line.
|
||||||
|
|
||||||
|
**Example feature**
|
||||||
|
|
||||||
|
```js
|
||||||
|
OPT(AST_Debugger, function(self, compressor) {
|
||||||
|
if (compressor.option("drop_debugger"))
|
||||||
|
return make_node(AST_EmptyStatement, self);
|
||||||
|
return self;
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example test case**
|
||||||
|
|
||||||
|
```js
|
||||||
|
drop_debugger: {
|
||||||
|
options = {
|
||||||
|
drop_debugger: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
debugger;
|
||||||
|
if (foo) debugger;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
if (foo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
|||||||
UglifyJS is released under the BSD license:
|
UglifyJS is released under the BSD license:
|
||||||
|
|
||||||
Copyright 2012-2013 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
Copyright 2012-2018 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions
|
modification, are permitted provided that the following conditions
|
||||||
|
|||||||
43
README.md
43
README.md
@@ -70,7 +70,7 @@ a double dash to prevent input files being used as option arguments:
|
|||||||
`debug` Add debug prefix and suffix.
|
`debug` Add debug prefix and suffix.
|
||||||
`domprops` Mangle property names that overlaps
|
`domprops` Mangle property names that overlaps
|
||||||
with DOM properties.
|
with DOM properties.
|
||||||
`keep_quoted` Only mangle unquoted properies.
|
`keep_quoted` Only mangle unquoted properties.
|
||||||
`regex` Only mangle matched property names.
|
`regex` Only mangle matched property names.
|
||||||
`reserved` List of names that should not be mangled.
|
`reserved` List of names that should not be mangled.
|
||||||
-b, --beautify [options] Beautify output/specify output options:
|
-b, --beautify [options] Beautify output/specify output options:
|
||||||
@@ -640,7 +640,13 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
|||||||
|
|
||||||
- `if_return` (default: `true`) -- optimizations for if/return and if/continue
|
- `if_return` (default: `true`) -- optimizations for if/return and if/continue
|
||||||
|
|
||||||
- `inline` (default: `true`) -- embed simple functions
|
- `inline` (default: `true`) -- inline calls to function with simple/`return` statement:
|
||||||
|
- `false` -- same as `0`
|
||||||
|
- `0` -- disabled inlining
|
||||||
|
- `1` -- inline simple functions
|
||||||
|
- `2` -- inline functions with arguments
|
||||||
|
- `3` -- inline functions with arguments and variables
|
||||||
|
- `true` -- same as `3`
|
||||||
|
|
||||||
- `join_vars` (default: `true`) -- join consecutive `var` statements
|
- `join_vars` (default: `true`) -- join consecutive `var` statements
|
||||||
|
|
||||||
@@ -731,7 +737,7 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
|||||||
comparison are switching. Compression only works if both `comparisons` and
|
comparison are switching. Compression only works if both `comparisons` and
|
||||||
`unsafe_comps` are both set to true.
|
`unsafe_comps` are both set to true.
|
||||||
|
|
||||||
- `unsafe_Func` (default: `false`) -- compress and mangle `Function(args, code)`
|
- `unsafe_Function` (default: `false`) -- compress and mangle `Function(args, code)`
|
||||||
when both `args` and `code` are string literals.
|
when both `args` and `code` are string literals.
|
||||||
|
|
||||||
- `unsafe_math` (default: `false`) -- optimize numerical expressions like
|
- `unsafe_math` (default: `false`) -- optimize numerical expressions like
|
||||||
@@ -743,6 +749,10 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
|||||||
- `unsafe_regexp` (default: `false`) -- enable substitutions of variables with
|
- `unsafe_regexp` (default: `false`) -- enable substitutions of variables with
|
||||||
`RegExp` values the same way as if they are constants.
|
`RegExp` values the same way as if they are constants.
|
||||||
|
|
||||||
|
- `unsafe_undefined` (default: `false`) -- substitute `void 0` if there is a
|
||||||
|
variable named `undefined` in scope (variable name will be mangled, typically
|
||||||
|
reduced to a single character)
|
||||||
|
|
||||||
- `unused` (default: `true`) -- drop unreferenced functions and variables (simple
|
- `unused` (default: `true`) -- drop unreferenced functions and variables (simple
|
||||||
direct variable assignments do not count as references unless set to `"keep_assign"`)
|
direct variable assignments do not count as references unless set to `"keep_assign"`)
|
||||||
|
|
||||||
@@ -916,9 +926,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`
|
||||||
- `void 0` → `undefined` (if there is a variable named "undefined" in
|
|
||||||
scope; we do it because the variable name will be mangled, typically
|
|
||||||
reduced to a single character)
|
|
||||||
|
|
||||||
### Conditional compilation
|
### Conditional compilation
|
||||||
|
|
||||||
@@ -1095,3 +1102,27 @@ To enable fast minify mode with the API use:
|
|||||||
```js
|
```js
|
||||||
UglifyJS.minify(code, { compress: false, mangle: true });
|
UglifyJS.minify(code, { compress: false, mangle: true });
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Source maps and debugging
|
||||||
|
|
||||||
|
Various `compress` transforms that simplify, rearrange, inline and remove code
|
||||||
|
are known to have an adverse effect on debugging with source maps. This is
|
||||||
|
expected as code is optimized and mappings are often simply not possible as
|
||||||
|
some code no longer exists. For highest fidelity in source map debugging
|
||||||
|
disable the Uglify `compress` option and just use `mangle`.
|
||||||
|
|
||||||
|
### Compiler assumptions
|
||||||
|
|
||||||
|
To allow for better optimizations, the compiler makes various assumptions:
|
||||||
|
|
||||||
|
- `.toString()` and `.valueOf()` don't have side effects, and for built-in
|
||||||
|
objects they have not been overridden.
|
||||||
|
- `undefined`, `NaN` and `Infinity` have not been externally redefined.
|
||||||
|
- `arguments.callee`, `arguments.caller` and `Function.prototype.caller` are not used.
|
||||||
|
- The code doesn't expect the contents of `Function.prototype.toString()` or
|
||||||
|
`Error.prototype.stack` to be anything in particular.
|
||||||
|
- Getting and setting properties on a plain object does not cause other side effects
|
||||||
|
(using `.watch()` or `Proxy`).
|
||||||
|
- Object properties can be added, removed and modified (not prevented with
|
||||||
|
`Object.defineProperty()`, `Object.defineProperties()`, `Object.freeze()`,
|
||||||
|
`Object.preventExtensions()` or `Object.seal()`).
|
||||||
|
|||||||
28
appveyor.yml
28
appveyor.yml
@@ -1,24 +1,20 @@
|
|||||||
environment:
|
environment:
|
||||||
matrix:
|
matrix:
|
||||||
- nodejs_version: "0.10"
|
- nodejs_version: "0.10"
|
||||||
- nodejs_version: "0.12"
|
- nodejs_version: "0.12"
|
||||||
- nodejs_version: "4.0"
|
- nodejs_version: "4"
|
||||||
- nodejs_version: "6.0"
|
- nodejs_version: "6"
|
||||||
|
- nodejs_version: "8"
|
||||||
|
install:
|
||||||
|
- ps: Install-Product node $env:nodejs_version
|
||||||
|
- set UGLIFYJS_TEST_ALL=1
|
||||||
|
- npm install
|
||||||
|
build: off
|
||||||
|
cache:
|
||||||
|
- tmp
|
||||||
matrix:
|
matrix:
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
|
|
||||||
platform:
|
|
||||||
- x86
|
|
||||||
- x64
|
|
||||||
|
|
||||||
install:
|
|
||||||
- ps: Install-Product node $env:nodejs_version $env:platform
|
|
||||||
- npm install
|
|
||||||
|
|
||||||
test_script:
|
test_script:
|
||||||
- node --version
|
- node --version
|
||||||
- npm --version
|
- npm --version
|
||||||
- npm test
|
- npm test
|
||||||
|
|
||||||
build: off
|
|
||||||
|
|||||||
35
bin/uglifyjs
35
bin/uglifyjs
@@ -3,11 +3,7 @@
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// workaround for tty output truncation upon process.exit()
|
require("../tools/exit");
|
||||||
[process.stdout, process.stderr].forEach(function(stream){
|
|
||||||
if (stream._handle && stream._handle.setBlocking)
|
|
||||||
stream._handle.setBlocking(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
var info = require("../package.json");
|
var info = require("../package.json");
|
||||||
@@ -15,7 +11,7 @@ var path = require("path");
|
|||||||
var program = require("commander");
|
var program = require("commander");
|
||||||
var UglifyJS = require("../tools/node");
|
var UglifyJS = require("../tools/node");
|
||||||
|
|
||||||
var skip_keys = [ "cname", "enclosed", "inlined", "parent_scope", "scope", "thedef", "uses_eval", "uses_with" ];
|
var skip_keys = [ "cname", "inlined", "parent_scope", "scope", "uses_eval", "uses_with" ];
|
||||||
var files = {};
|
var files = {};
|
||||||
var options = {
|
var options = {
|
||||||
compress: false,
|
compress: false,
|
||||||
@@ -47,6 +43,7 @@ program.option("-d, --define <expr>[=value]", "Global definitions.", parse_js("d
|
|||||||
program.option("--ie8", "Support non-standard Internet Explorer 8.");
|
program.option("--ie8", "Support non-standard Internet Explorer 8.");
|
||||||
program.option("--keep-fnames", "Do not mangle/drop function names. Useful for code relying on Function.prototype.name.");
|
program.option("--keep-fnames", "Do not mangle/drop function names. Useful for code relying on Function.prototype.name.");
|
||||||
program.option("--name-cache <file>", "File to hold mangled name mappings.");
|
program.option("--name-cache <file>", "File to hold mangled name mappings.");
|
||||||
|
program.option("--rename", "Force symbol expansion.");
|
||||||
program.option("--no-rename", "Disable symbol expansion.");
|
program.option("--no-rename", "Disable symbol expansion.");
|
||||||
program.option("--self", "Build UglifyJS as a library (implies --wrap UglifyJS)");
|
program.option("--self", "Build UglifyJS as a library (implies --wrap UglifyJS)");
|
||||||
program.option("--source-map [options]", "Enable source map/specify source map options.", parse_source_map());
|
program.option("--source-map [options]", "Enable source map/specify source map options.", parse_source_map());
|
||||||
@@ -66,13 +63,11 @@ if (!program.output && program.sourceMap && program.sourceMap.url != "inline") {
|
|||||||
"compress",
|
"compress",
|
||||||
"ie8",
|
"ie8",
|
||||||
"mangle",
|
"mangle",
|
||||||
"rename",
|
|
||||||
"sourceMap",
|
"sourceMap",
|
||||||
"toplevel",
|
"toplevel",
|
||||||
"wrap"
|
"wrap"
|
||||||
].forEach(function(name) {
|
].forEach(function(name) {
|
||||||
if (name in program) {
|
if (name in program) {
|
||||||
if (name == "rename" && program[name]) return;
|
|
||||||
options[name] = program[name];
|
options[name] = program[name];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -125,6 +120,11 @@ if (program.parse) {
|
|||||||
fatal("ERROR: inline source map only works with built-in parser");
|
fatal("ERROR: inline source map only works with built-in parser");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (~program.rawArgs.indexOf("--rename")) {
|
||||||
|
options.rename = true;
|
||||||
|
} else if (!program.rename) {
|
||||||
|
options.rename = false;
|
||||||
|
}
|
||||||
var convert_path = function(name) {
|
var convert_path = function(name) {
|
||||||
return name;
|
return name;
|
||||||
};
|
};
|
||||||
@@ -227,7 +227,20 @@ function run() {
|
|||||||
}
|
}
|
||||||
fatal(ex);
|
fatal(ex);
|
||||||
} else if (program.output == "ast") {
|
} else if (program.output == "ast") {
|
||||||
|
if (!options.compress && !options.mangle) {
|
||||||
|
result.ast.figure_out_scope({});
|
||||||
|
}
|
||||||
print(JSON.stringify(result.ast, function(key, value) {
|
print(JSON.stringify(result.ast, function(key, value) {
|
||||||
|
if (value) switch (key) {
|
||||||
|
case "thedef":
|
||||||
|
return symdef(value);
|
||||||
|
case "enclosed":
|
||||||
|
return value.length ? value.map(symdef) : undefined;
|
||||||
|
case "variables":
|
||||||
|
case "functions":
|
||||||
|
case "globals":
|
||||||
|
return value.size() ? value.map(symdef) : undefined;
|
||||||
|
}
|
||||||
if (skip_key(key)) return;
|
if (skip_key(key)) return;
|
||||||
if (value instanceof UglifyJS.AST_Token) return;
|
if (value instanceof UglifyJS.AST_Token) return;
|
||||||
if (value instanceof UglifyJS.Dictionary) return;
|
if (value instanceof UglifyJS.Dictionary) return;
|
||||||
@@ -381,6 +394,12 @@ function skip_key(key) {
|
|||||||
return skip_keys.indexOf(key) >= 0;
|
return skip_keys.indexOf(key) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function symdef(def) {
|
||||||
|
var ret = (1e6 + def.id) + " " + def.name;
|
||||||
|
if (def.mangled_name) ret += " " + def.mangled_name;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
function format_object(obj) {
|
function format_object(obj) {
|
||||||
var lines = [];
|
var lines = [];
|
||||||
var padding = "";
|
var padding = "";
|
||||||
|
|||||||
14
lib/ast.js
14
lib/ast.js
@@ -267,11 +267,10 @@ var AST_For = DEFNODE("For", "init condition step", {
|
|||||||
}
|
}
|
||||||
}, AST_IterationStatement);
|
}, AST_IterationStatement);
|
||||||
|
|
||||||
var AST_ForIn = DEFNODE("ForIn", "init name object", {
|
var AST_ForIn = DEFNODE("ForIn", "init object", {
|
||||||
$documentation: "A `for ... in` statement",
|
$documentation: "A `for ... in` statement",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
init: "[AST_Node] the `for/in` initialization code",
|
init: "[AST_Node] the `for/in` initialization code",
|
||||||
name: "[AST_SymbolRef?] the loop variable, only if `init` is AST_Var",
|
|
||||||
object: "[AST_Node] the object that we're looping through"
|
object: "[AST_Node] the object that we're looping through"
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
_walk: function(visitor) {
|
||||||
@@ -309,6 +308,13 @@ var AST_Scope = DEFNODE("Scope", "variables functions uses_with uses_eval parent
|
|||||||
enclosed: "[SymbolDef*/S] a list of all symbol definitions that are accessed from this scope or any subscopes",
|
enclosed: "[SymbolDef*/S] a list of all symbol definitions that are accessed from this scope or any subscopes",
|
||||||
cname: "[integer/S] current index for mangling variables (used internally by the mangler)",
|
cname: "[integer/S] current index for mangling variables (used internally by the mangler)",
|
||||||
},
|
},
|
||||||
|
clone: function(deep) {
|
||||||
|
var node = this._clone(deep);
|
||||||
|
if (this.variables) node.variables = this.variables.clone();
|
||||||
|
if (this.functions) node.functions = this.functions.clone();
|
||||||
|
if (this.enclosed) node.enclosed = this.enclosed.slice();
|
||||||
|
return node;
|
||||||
|
}
|
||||||
}, AST_Block);
|
}, AST_Block);
|
||||||
|
|
||||||
var AST_Toplevel = DEFNODE("Toplevel", "globals", {
|
var AST_Toplevel = DEFNODE("Toplevel", "globals", {
|
||||||
@@ -683,8 +689,8 @@ var AST_Object = DEFNODE("Object", "properties", {
|
|||||||
var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", {
|
var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", {
|
||||||
$documentation: "Base class for literal object properties",
|
$documentation: "Base class for literal object properties",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
key: "[string] the property name converted to a string for ObjectKeyVal. For setters and getters this is an AST_SymbolAccessor.",
|
key: "[string|AST_SymbolAccessor] property name. For ObjectKeyVal this is a string. For getters and setters this is an AST_SymbolAccessor.",
|
||||||
value: "[AST_Node] property value. For setters and getters this is an AST_Accessor."
|
value: "[AST_Node] property value. For getters and setters this is an AST_Accessor."
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
_walk: function(visitor) {
|
||||||
return visitor._visit(this, function(){
|
return visitor._visit(this, function(){
|
||||||
|
|||||||
1451
lib/compress.js
1451
lib/compress.js
File diff suppressed because it is too large
Load Diff
@@ -29,7 +29,6 @@ function set_shorthand(name, options, keys) {
|
|||||||
|
|
||||||
function init_cache(cache) {
|
function init_cache(cache) {
|
||||||
if (!cache) return;
|
if (!cache) return;
|
||||||
if (!("cname" in cache)) cache.cname = -1;
|
|
||||||
if (!("props" in cache)) {
|
if (!("props" in cache)) {
|
||||||
cache.props = new Dictionary();
|
cache.props = new Dictionary();
|
||||||
} else if (!(cache.props instanceof Dictionary)) {
|
} else if (!(cache.props instanceof Dictionary)) {
|
||||||
@@ -39,7 +38,6 @@ function init_cache(cache) {
|
|||||||
|
|
||||||
function to_json(cache) {
|
function to_json(cache) {
|
||||||
return {
|
return {
|
||||||
cname: cache.cname,
|
|
||||||
props: cache.props.toObject()
|
props: cache.props.toObject()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
198
lib/output.js
198
lib/output.js
@@ -451,81 +451,86 @@ function OutputStream(options) {
|
|||||||
return OUTPUT;
|
return OUTPUT;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function has_nlb() {
|
||||||
|
var index = OUTPUT.lastIndexOf("\n");
|
||||||
|
return /^ *$/.test(OUTPUT.slice(index + 1));
|
||||||
|
}
|
||||||
|
|
||||||
function prepend_comments(node) {
|
function prepend_comments(node) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var start = node.start;
|
var start = node.start;
|
||||||
if (!(start.comments_before && start.comments_before._dumped === self)) {
|
if (!start) return;
|
||||||
var comments = start.comments_before;
|
if (start.comments_before && start.comments_before._dumped === self) return;
|
||||||
if (!comments) {
|
var comments = start.comments_before;
|
||||||
comments = start.comments_before = [];
|
if (!comments) {
|
||||||
}
|
comments = start.comments_before = [];
|
||||||
comments._dumped = self;
|
}
|
||||||
|
comments._dumped = self;
|
||||||
|
|
||||||
if (node instanceof AST_Exit && node.value) {
|
if (node instanceof AST_Exit && node.value) {
|
||||||
var tw = new TreeWalker(function(node) {
|
var tw = new TreeWalker(function(node) {
|
||||||
var parent = tw.parent();
|
var parent = tw.parent();
|
||||||
if (parent instanceof AST_Exit
|
if (parent instanceof AST_Exit
|
||||||
|| parent instanceof AST_Binary && parent.left === node
|
|| parent instanceof AST_Binary && parent.left === node
|
||||||
|| parent.TYPE == "Call" && parent.expression === node
|
|| parent.TYPE == "Call" && parent.expression === node
|
||||||
|| parent instanceof AST_Conditional && parent.condition === node
|
|| parent instanceof AST_Conditional && parent.condition === node
|
||||||
|| parent instanceof AST_Dot && parent.expression === node
|
|| parent instanceof AST_Dot && parent.expression === node
|
||||||
|| parent instanceof AST_Sequence && parent.expressions[0] === node
|
|| parent instanceof AST_Sequence && parent.expressions[0] === node
|
||||||
|| parent instanceof AST_Sub && parent.expression === node
|
|| parent instanceof AST_Sub && parent.expression === node
|
||||||
|| parent instanceof AST_UnaryPostfix) {
|
|| parent instanceof AST_UnaryPostfix) {
|
||||||
var text = node.start.comments_before;
|
var text = node.start.comments_before;
|
||||||
if (text && text._dumped !== self) {
|
if (text && text._dumped !== self) {
|
||||||
text._dumped = self;
|
text._dumped = self;
|
||||||
comments = comments.concat(text);
|
comments = comments.concat(text);
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
});
|
} else {
|
||||||
tw.push(node);
|
return true;
|
||||||
node.value.walk(tw);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (current_pos == 0) {
|
|
||||||
if (comments.length > 0 && options.shebang && comments[0].type == "comment5") {
|
|
||||||
print("#!" + comments.shift().value + "\n");
|
|
||||||
indent();
|
|
||||||
}
|
|
||||||
var preamble = options.preamble;
|
|
||||||
if (preamble) {
|
|
||||||
print(preamble.replace(/\r\n?|[\n\u2028\u2029]|\s*$/g, "\n"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
comments = comments.filter(comment_filter, node);
|
|
||||||
if (comments.length == 0) return;
|
|
||||||
var last_nlb = /(^|\n) *$/.test(OUTPUT);
|
|
||||||
comments.forEach(function(c, i) {
|
|
||||||
if (!last_nlb) {
|
|
||||||
if (c.nlb) {
|
|
||||||
print("\n");
|
|
||||||
indent();
|
|
||||||
last_nlb = true;
|
|
||||||
} else if (i > 0) {
|
|
||||||
space();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (/comment[134]/.test(c.type)) {
|
|
||||||
print("//" + c.value.replace(/[@#]__PURE__/g, ' ') + "\n");
|
|
||||||
indent();
|
|
||||||
last_nlb = true;
|
|
||||||
} else if (c.type == "comment2") {
|
|
||||||
print("/*" + c.value.replace(/[@#]__PURE__/g, ' ') + "*/");
|
|
||||||
last_nlb = false;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
tw.push(node);
|
||||||
|
node.value.walk(tw);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current_pos == 0) {
|
||||||
|
if (comments.length > 0 && options.shebang && comments[0].type == "comment5") {
|
||||||
|
print("#!" + comments.shift().value + "\n");
|
||||||
|
indent();
|
||||||
|
}
|
||||||
|
var preamble = options.preamble;
|
||||||
|
if (preamble) {
|
||||||
|
print(preamble.replace(/\r\n?|[\n\u2028\u2029]|\s*$/g, "\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
comments = comments.filter(comment_filter, node);
|
||||||
|
if (comments.length == 0) return;
|
||||||
|
var last_nlb = has_nlb();
|
||||||
|
comments.forEach(function(c, i) {
|
||||||
if (!last_nlb) {
|
if (!last_nlb) {
|
||||||
if (start.nlb) {
|
if (c.nlb) {
|
||||||
print("\n");
|
print("\n");
|
||||||
indent();
|
indent();
|
||||||
} else {
|
last_nlb = true;
|
||||||
|
} else if (i > 0) {
|
||||||
space();
|
space();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (/comment[134]/.test(c.type)) {
|
||||||
|
print("//" + c.value.replace(/[@#]__PURE__/g, ' ') + "\n");
|
||||||
|
indent();
|
||||||
|
last_nlb = true;
|
||||||
|
} else if (c.type == "comment2") {
|
||||||
|
print("/*" + c.value.replace(/[@#]__PURE__/g, ' ') + "*/");
|
||||||
|
last_nlb = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!last_nlb) {
|
||||||
|
if (start.nlb) {
|
||||||
|
print("\n");
|
||||||
|
indent();
|
||||||
|
} else {
|
||||||
|
space();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -534,31 +539,33 @@ function OutputStream(options) {
|
|||||||
var token = node.end;
|
var token = node.end;
|
||||||
if (!token) return;
|
if (!token) return;
|
||||||
var comments = token[tail ? "comments_before" : "comments_after"];
|
var comments = token[tail ? "comments_before" : "comments_after"];
|
||||||
if (comments && comments._dumped !== self) {
|
if (!comments || comments._dumped === self) return;
|
||||||
comments._dumped = self;
|
if (!(node instanceof AST_Statement || all(comments, function(c) {
|
||||||
var insert = OUTPUT.length;
|
return !/comment[134]/.test(c.type);
|
||||||
comments.filter(comment_filter, node).forEach(function(c, i) {
|
}))) return;
|
||||||
need_space = false;
|
comments._dumped = self;
|
||||||
if (need_newline_indented) {
|
var insert = OUTPUT.length;
|
||||||
print("\n");
|
comments.filter(comment_filter, node).forEach(function(c, i) {
|
||||||
indent();
|
need_space = false;
|
||||||
need_newline_indented = false;
|
if (need_newline_indented) {
|
||||||
} else if (c.nlb && (i > 0 || !/(^|\n) *$/.test(OUTPUT))) {
|
print("\n");
|
||||||
print("\n");
|
indent();
|
||||||
indent();
|
need_newline_indented = false;
|
||||||
} else if (i > 0 || !tail) {
|
} else if (c.nlb && (i > 0 || !has_nlb())) {
|
||||||
space();
|
print("\n");
|
||||||
}
|
indent();
|
||||||
if (/comment[134]/.test(c.type)) {
|
} else if (i > 0 || !tail) {
|
||||||
print("//" + c.value.replace(/[@#]__PURE__/g, ' '));
|
space();
|
||||||
need_newline_indented = true;
|
}
|
||||||
} else if (c.type == "comment2") {
|
if (/comment[134]/.test(c.type)) {
|
||||||
print("/*" + c.value.replace(/[@#]__PURE__/g, ' ') + "*/");
|
print("//" + c.value.replace(/[@#]__PURE__/g, ' '));
|
||||||
need_space = true;
|
need_newline_indented = true;
|
||||||
}
|
} else if (c.type == "comment2") {
|
||||||
});
|
print("/*" + c.value.replace(/[@#]__PURE__/g, ' ') + "*/");
|
||||||
if (OUTPUT.length > insert) newline_insert = insert;
|
need_space = true;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
if (OUTPUT.length > insert) newline_insert = insert;
|
||||||
}
|
}
|
||||||
|
|
||||||
var stack = [];
|
var stack = [];
|
||||||
@@ -599,7 +606,7 @@ function OutputStream(options) {
|
|||||||
add_mapping : add_mapping,
|
add_mapping : add_mapping,
|
||||||
option : function(opt) { return options[opt] },
|
option : function(opt) { return options[opt] },
|
||||||
prepend_comments: readonly ? noop : prepend_comments,
|
prepend_comments: readonly ? noop : prepend_comments,
|
||||||
append_comments : readonly ? noop : append_comments,
|
append_comments : readonly || comment_filter === return_false ? noop : append_comments,
|
||||||
line : function() { return current_line },
|
line : function() { return current_line },
|
||||||
col : function() { return current_col },
|
col : function() { return current_col },
|
||||||
pos : function() { return current_pos },
|
pos : function() { return current_pos },
|
||||||
@@ -671,9 +678,7 @@ function OutputStream(options) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
PARENS(AST_Node, function(){
|
PARENS(AST_Node, return_false);
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
// a function expression needs parens around it when it's provably
|
// a function expression needs parens around it when it's provably
|
||||||
// the first token to appear in a statement.
|
// the first token to appear in a statement.
|
||||||
@@ -699,9 +704,7 @@ function OutputStream(options) {
|
|||||||
|
|
||||||
// same goes for an object literal, because otherwise it would be
|
// same goes for an object literal, because otherwise it would be
|
||||||
// interpreted as a block of code.
|
// interpreted as a block of code.
|
||||||
PARENS(AST_Object, function(output){
|
PARENS(AST_Object, first_in_statement);
|
||||||
return first_in_statement(output);
|
|
||||||
});
|
|
||||||
|
|
||||||
PARENS(AST_Unary, function(output){
|
PARENS(AST_Unary, function(output){
|
||||||
var p = output.parent();
|
var p = output.parent();
|
||||||
@@ -1346,11 +1349,8 @@ function OutputStream(options) {
|
|||||||
|
|
||||||
function print_property_name(key, quote, output) {
|
function print_property_name(key, quote, output) {
|
||||||
if (output.option("quote_keys")) {
|
if (output.option("quote_keys")) {
|
||||||
output.print_string(key + "");
|
output.print_string(key);
|
||||||
} else if ((typeof key == "number"
|
} else if ("" + +key == key && key >= 0) {
|
||||||
|| !output.option("beautify")
|
|
||||||
&& +key + "" == key)
|
|
||||||
&& parseFloat(key) >= 0) {
|
|
||||||
output.print(make_num(key));
|
output.print(make_num(key));
|
||||||
} else if (RESERVED_WORDS(key) ? !output.option("ie8") : is_identifier_string(key)) {
|
} else if (RESERVED_WORDS(key) ? !output.option("ie8") : is_identifier_string(key)) {
|
||||||
if (quote && output.option("keep_quoted_props")) {
|
if (quote && output.option("keep_quoted_props")) {
|
||||||
|
|||||||
50
lib/parse.js
50
lib/parse.js
@@ -774,10 +774,15 @@ function parse($TEXT, options) {
|
|||||||
|
|
||||||
function expect(punc) { return expect_token("punc", punc); };
|
function expect(punc) { return expect_token("punc", punc); };
|
||||||
|
|
||||||
|
function has_newline_before(token) {
|
||||||
|
return token.nlb || !all(token.comments_before, function(comment) {
|
||||||
|
return !comment.nlb;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function can_insert_semicolon() {
|
function can_insert_semicolon() {
|
||||||
return !options.strict && (
|
return !options.strict
|
||||||
S.token.nlb || is("eof") || is("punc", "}")
|
&& (is("eof") || is("punc", "}") || has_newline_before(S.token));
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function semicolon(optional) {
|
function semicolon(optional) {
|
||||||
@@ -795,7 +800,7 @@ function parse($TEXT, options) {
|
|||||||
function embed_tokens(parser) {
|
function embed_tokens(parser) {
|
||||||
return function() {
|
return function() {
|
||||||
var start = S.token;
|
var start = S.token;
|
||||||
var expr = parser();
|
var expr = parser.apply(null, arguments);
|
||||||
var end = prev();
|
var end = prev();
|
||||||
expr.start = start;
|
expr.start = start;
|
||||||
expr.end = end;
|
expr.end = end;
|
||||||
@@ -810,17 +815,17 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var statement = embed_tokens(function() {
|
var statement = embed_tokens(function(strict_defun) {
|
||||||
handle_regexp();
|
handle_regexp();
|
||||||
switch (S.token.type) {
|
switch (S.token.type) {
|
||||||
case "string":
|
case "string":
|
||||||
if (S.in_directives) {
|
if (S.in_directives) {
|
||||||
var token = peek();
|
var token = peek();
|
||||||
if (S.token.raw.indexOf("\\") == -1
|
if (S.token.raw.indexOf("\\") == -1
|
||||||
&& (token.nlb
|
&& (is_token(token, "punc", ";")
|
||||||
|| is_token(token, "eof")
|
|| is_token(token, "punc", "}")
|
||||||
|| is_token(token, "punc", ";")
|
|| has_newline_before(token)
|
||||||
|| is_token(token, "punc", "}"))) {
|
|| is_token(token, "eof"))) {
|
||||||
S.input.add_directive(S.token.value);
|
S.input.add_directive(S.token.value);
|
||||||
} else {
|
} else {
|
||||||
S.in_directives = false;
|
S.in_directives = false;
|
||||||
@@ -896,6 +901,9 @@ function parse($TEXT, options) {
|
|||||||
return for_();
|
return for_();
|
||||||
|
|
||||||
case "function":
|
case "function":
|
||||||
|
if (!strict_defun && S.input.has_directive("use strict")) {
|
||||||
|
croak("In strict mode code, functions can only be declared at top level or immediately within another function.");
|
||||||
|
}
|
||||||
next();
|
next();
|
||||||
return function_(AST_Defun);
|
return function_(AST_Defun);
|
||||||
|
|
||||||
@@ -927,7 +935,7 @@ function parse($TEXT, options) {
|
|||||||
|
|
||||||
case "throw":
|
case "throw":
|
||||||
next();
|
next();
|
||||||
if (S.token.nlb)
|
if (has_newline_before(S.token))
|
||||||
croak("Illegal newline after 'throw'");
|
croak("Illegal newline after 'throw'");
|
||||||
var value = expression(true);
|
var value = expression(true);
|
||||||
semicolon();
|
semicolon();
|
||||||
@@ -1046,12 +1054,10 @@ function parse($TEXT, options) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function for_in(init) {
|
function for_in(init) {
|
||||||
var lhs = init instanceof AST_Var ? init.definitions[0].name : null;
|
|
||||||
var obj = expression(true);
|
var obj = expression(true);
|
||||||
expect(")");
|
expect(")");
|
||||||
return new AST_ForIn({
|
return new AST_ForIn({
|
||||||
init : init,
|
init : init,
|
||||||
name : lhs,
|
|
||||||
object : obj,
|
object : obj,
|
||||||
body : in_loop(statement)
|
body : in_loop(statement)
|
||||||
});
|
});
|
||||||
@@ -1078,7 +1084,7 @@ function parse($TEXT, options) {
|
|||||||
S.input.push_directives_stack();
|
S.input.push_directives_stack();
|
||||||
S.in_loop = 0;
|
S.in_loop = 0;
|
||||||
S.labels = [];
|
S.labels = [];
|
||||||
var body = block_();
|
var body = block_(true);
|
||||||
if (S.input.has_directive("use strict")) {
|
if (S.input.has_directive("use strict")) {
|
||||||
if (name) strict_verify_symbol(name);
|
if (name) strict_verify_symbol(name);
|
||||||
argnames.forEach(strict_verify_symbol);
|
argnames.forEach(strict_verify_symbol);
|
||||||
@@ -1107,12 +1113,12 @@ function parse($TEXT, options) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function block_() {
|
function block_(strict_defun) {
|
||||||
expect("{");
|
expect("{");
|
||||||
var a = [];
|
var a = [];
|
||||||
while (!is("punc", "}")) {
|
while (!is("punc", "}")) {
|
||||||
if (is("eof")) unexpected();
|
if (is("eof")) unexpected();
|
||||||
a.push(statement());
|
a.push(statement(strict_defun));
|
||||||
}
|
}
|
||||||
next();
|
next();
|
||||||
return a;
|
return a;
|
||||||
@@ -1220,12 +1226,14 @@ function parse($TEXT, options) {
|
|||||||
} else {
|
} else {
|
||||||
args = [];
|
args = [];
|
||||||
}
|
}
|
||||||
return subscripts(new AST_New({
|
var call = new AST_New({
|
||||||
start : start,
|
start : start,
|
||||||
expression : newexp,
|
expression : newexp,
|
||||||
args : args,
|
args : args,
|
||||||
end : prev()
|
end : prev()
|
||||||
}), allow_calls);
|
});
|
||||||
|
mark_pure(call);
|
||||||
|
return subscripts(call, allow_calls);
|
||||||
};
|
};
|
||||||
|
|
||||||
function as_atom_node() {
|
function as_atom_node() {
|
||||||
@@ -1357,7 +1365,7 @@ function parse($TEXT, options) {
|
|||||||
if (type == "name" && !is("punc", ":")) {
|
if (type == "name" && !is("punc", ":")) {
|
||||||
var key = new AST_SymbolAccessor({
|
var key = new AST_SymbolAccessor({
|
||||||
start: S.token,
|
start: S.token,
|
||||||
name: as_property_name(),
|
name: "" + as_property_name(),
|
||||||
end: prev()
|
end: prev()
|
||||||
});
|
});
|
||||||
if (name == "get") {
|
if (name == "get") {
|
||||||
@@ -1383,7 +1391,7 @@ function parse($TEXT, options) {
|
|||||||
a.push(new AST_ObjectKeyVal({
|
a.push(new AST_ObjectKeyVal({
|
||||||
start : start,
|
start : start,
|
||||||
quote : start.quote,
|
quote : start.quote,
|
||||||
key : name,
|
key : "" + name,
|
||||||
value : expression(false),
|
value : expression(false),
|
||||||
end : prev()
|
end : prev()
|
||||||
}));
|
}));
|
||||||
@@ -1503,7 +1511,7 @@ function parse($TEXT, options) {
|
|||||||
return ex;
|
return ex;
|
||||||
}
|
}
|
||||||
var val = expr_atom(allow_calls);
|
var val = expr_atom(allow_calls);
|
||||||
while (is("operator") && UNARY_POSTFIX(S.token.value) && !S.token.nlb) {
|
while (is("operator") && UNARY_POSTFIX(S.token.value) && !has_newline_before(S.token)) {
|
||||||
val = make_unary(AST_UnaryPostfix, S.token, val);
|
val = make_unary(AST_UnaryPostfix, S.token, val);
|
||||||
val.start = start;
|
val.start = start;
|
||||||
val.end = S.token;
|
val.end = S.token;
|
||||||
@@ -1623,7 +1631,7 @@ function parse($TEXT, options) {
|
|||||||
var body = [];
|
var body = [];
|
||||||
S.input.push_directives_stack();
|
S.input.push_directives_stack();
|
||||||
while (!is("eof"))
|
while (!is("eof"))
|
||||||
body.push(statement());
|
body.push(statement(true));
|
||||||
S.input.pop_directives_stack();
|
S.input.pop_directives_stack();
|
||||||
var end = prev();
|
var end = prev();
|
||||||
var toplevel = options.toplevel;
|
var toplevel = options.toplevel;
|
||||||
|
|||||||
@@ -110,12 +110,15 @@ function mangle_properties(ast, options) {
|
|||||||
if (!Array.isArray(reserved)) reserved = [];
|
if (!Array.isArray(reserved)) reserved = [];
|
||||||
if (!options.builtins) find_builtins(reserved);
|
if (!options.builtins) find_builtins(reserved);
|
||||||
|
|
||||||
var cache = options.cache;
|
var cname = -1;
|
||||||
if (cache == null) {
|
var cache;
|
||||||
cache = {
|
if (options.cache) {
|
||||||
cname: -1,
|
cache = options.cache.props;
|
||||||
props: new Dictionary()
|
cache.each(function(mangled_name) {
|
||||||
};
|
push_uniq(reserved, mangled_name);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
cache = new Dictionary();
|
||||||
}
|
}
|
||||||
|
|
||||||
var regex = options.regex;
|
var regex = options.regex;
|
||||||
@@ -172,7 +175,7 @@ function mangle_properties(ast, options) {
|
|||||||
if (unmangleable.indexOf(name) >= 0) return false;
|
if (unmangleable.indexOf(name) >= 0) return false;
|
||||||
if (reserved.indexOf(name) >= 0) return false;
|
if (reserved.indexOf(name) >= 0) return false;
|
||||||
if (options.only_cache) {
|
if (options.only_cache) {
|
||||||
return cache.props.has(name);
|
return cache.has(name);
|
||||||
}
|
}
|
||||||
if (/^-?[0-9]+(\.[0-9]+)?(e[+-][0-9]+)?$/.test(name)) return false;
|
if (/^-?[0-9]+(\.[0-9]+)?(e[+-][0-9]+)?$/.test(name)) return false;
|
||||||
return true;
|
return true;
|
||||||
@@ -181,7 +184,7 @@ function mangle_properties(ast, options) {
|
|||||||
function should_mangle(name) {
|
function should_mangle(name) {
|
||||||
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.has(name)
|
||||||
|| names_to_mangle.indexOf(name) >= 0;
|
|| names_to_mangle.indexOf(name) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,7 +202,7 @@ function mangle_properties(ast, options) {
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
var mangled = cache.props.get(name);
|
var mangled = cache.get(name);
|
||||||
if (!mangled) {
|
if (!mangled) {
|
||||||
if (debug) {
|
if (debug) {
|
||||||
// debug mode: use a prefix and suffix to preserve readability, e.g. o.foo -> o._$foo$NNN_.
|
// debug mode: use a prefix and suffix to preserve readability, e.g. o.foo -> o._$foo$NNN_.
|
||||||
@@ -213,11 +216,11 @@ function mangle_properties(ast, options) {
|
|||||||
// 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) {
|
||||||
do {
|
do {
|
||||||
mangled = base54(++cache.cname);
|
mangled = base54(++cname);
|
||||||
} while (!can_mangle(mangled));
|
} while (!can_mangle(mangled));
|
||||||
}
|
}
|
||||||
|
|
||||||
cache.props.set(name, mangled);
|
cache.set(name, mangled);
|
||||||
}
|
}
|
||||||
return mangled;
|
return mangled;
|
||||||
}
|
}
|
||||||
|
|||||||
114
lib/scope.js
114
lib/scope.js
@@ -43,9 +43,10 @@
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
function SymbolDef(scope, orig) {
|
function SymbolDef(scope, orig, init) {
|
||||||
this.name = orig.name;
|
this.name = orig.name;
|
||||||
this.orig = [ orig ];
|
this.orig = [ orig ];
|
||||||
|
this.init = init;
|
||||||
this.eliminated = 0;
|
this.eliminated = 0;
|
||||||
this.scope = scope;
|
this.scope = scope;
|
||||||
this.references = [];
|
this.references = [];
|
||||||
@@ -150,7 +151,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
node.references = [];
|
node.references = [];
|
||||||
}
|
}
|
||||||
if (node instanceof AST_SymbolLambda) {
|
if (node instanceof AST_SymbolLambda) {
|
||||||
defun.def_function(node);
|
defun.def_function(node, node.name == "arguments" ? undefined : defun);
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_SymbolDefun) {
|
else if (node instanceof AST_SymbolDefun) {
|
||||||
// Careful here, the scope where this should be defined is
|
// Careful here, the scope where this should be defined is
|
||||||
@@ -158,10 +159,10 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
// scope when we encounter the AST_Defun node (which is
|
// scope when we encounter the AST_Defun node (which is
|
||||||
// instanceof AST_Scope) but we get to the symbol a bit
|
// instanceof AST_Scope) but we get to the symbol a bit
|
||||||
// later.
|
// later.
|
||||||
(node.scope = defun.parent_scope).def_function(node);
|
(node.scope = defun.parent_scope).def_function(node, defun);
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_SymbolVar) {
|
else if (node instanceof AST_SymbolVar) {
|
||||||
defun.def_variable(node);
|
defun.def_variable(node, node.TYPE == "SymbolVar" ? null : undefined);
|
||||||
if (defun !== scope) {
|
if (defun !== scope) {
|
||||||
node.mark_enclosed(options);
|
node.mark_enclosed(options);
|
||||||
var def = scope.find_variable(node);
|
var def = scope.find_variable(node);
|
||||||
@@ -241,10 +242,6 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.cache) {
|
|
||||||
this.cname = options.cache.cname;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Toplevel.DEFMETHOD("def_global", function(node){
|
AST_Toplevel.DEFMETHOD("def_global", function(node){
|
||||||
@@ -306,27 +303,32 @@ AST_Scope.DEFMETHOD("find_variable", function(name){
|
|||||||
|| (this.parent_scope && this.parent_scope.find_variable(name));
|
|| (this.parent_scope && this.parent_scope.find_variable(name));
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Scope.DEFMETHOD("def_function", function(symbol){
|
AST_Scope.DEFMETHOD("def_function", function(symbol, init){
|
||||||
this.functions.set(symbol.name, this.def_variable(symbol));
|
var def = this.def_variable(symbol, init);
|
||||||
|
if (!def.init || def.init instanceof AST_Defun) def.init = init;
|
||||||
|
this.functions.set(symbol.name, def);
|
||||||
|
return def;
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Scope.DEFMETHOD("def_variable", function(symbol){
|
AST_Scope.DEFMETHOD("def_variable", function(symbol, init){
|
||||||
var def;
|
var def = this.variables.get(symbol.name);
|
||||||
if (!this.variables.has(symbol.name)) {
|
if (def) {
|
||||||
def = new SymbolDef(this, symbol);
|
def.orig.push(symbol);
|
||||||
|
if (def.init && (def.scope !== symbol.scope || def.init instanceof AST_Function)) {
|
||||||
|
def.init = init;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
def = new SymbolDef(this, symbol, init);
|
||||||
this.variables.set(symbol.name, def);
|
this.variables.set(symbol.name, def);
|
||||||
def.global = !this.parent_scope;
|
def.global = !this.parent_scope;
|
||||||
} else {
|
|
||||||
def = this.variables.get(symbol.name);
|
|
||||||
def.orig.push(symbol);
|
|
||||||
}
|
}
|
||||||
return symbol.thedef = def;
|
return symbol.thedef = def;
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Scope.DEFMETHOD("next_mangled", function(options){
|
function next_mangled(scope, options) {
|
||||||
var ext = this.enclosed;
|
var ext = scope.enclosed;
|
||||||
out: while (true) {
|
out: while (true) {
|
||||||
var m = base54(++this.cname);
|
var m = base54(++scope.cname);
|
||||||
if (!is_identifier(m)) continue; // skip over "do"
|
if (!is_identifier(m)) continue; // skip over "do"
|
||||||
|
|
||||||
// https://github.com/mishoo/UglifyJS2/issues/242 -- do not
|
// https://github.com/mishoo/UglifyJS2/issues/242 -- do not
|
||||||
@@ -343,6 +345,18 @@ AST_Scope.DEFMETHOD("next_mangled", function(options){
|
|||||||
}
|
}
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AST_Scope.DEFMETHOD("next_mangled", function(options){
|
||||||
|
return next_mangled(this, options);
|
||||||
|
});
|
||||||
|
|
||||||
|
AST_Toplevel.DEFMETHOD("next_mangled", function(options){
|
||||||
|
var name;
|
||||||
|
do {
|
||||||
|
name = next_mangled(this, options);
|
||||||
|
} while (member(name, this.mangled_names));
|
||||||
|
return name;
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Function.DEFMETHOD("next_mangled", function(options, def){
|
AST_Function.DEFMETHOD("next_mangled", function(options, def){
|
||||||
@@ -356,7 +370,7 @@ AST_Function.DEFMETHOD("next_mangled", function(options, def){
|
|||||||
var tricky_name = tricky_def ? tricky_def.mangled_name || tricky_def.name : null;
|
var tricky_name = tricky_def ? tricky_def.mangled_name || tricky_def.name : null;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
var name = AST_Lambda.prototype.next_mangled.call(this, options, def);
|
var name = next_mangled(this, options);
|
||||||
if (!tricky_name || tricky_name != name)
|
if (!tricky_name || tricky_name != name)
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
@@ -407,8 +421,14 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
|||||||
var lname = -1;
|
var lname = -1;
|
||||||
var to_mangle = [];
|
var to_mangle = [];
|
||||||
|
|
||||||
|
var mangled_names = this.mangled_names = [];
|
||||||
if (options.cache) {
|
if (options.cache) {
|
||||||
this.globals.each(collect);
|
this.globals.each(collect);
|
||||||
|
if (options.cache.props) {
|
||||||
|
options.cache.props.each(function(mangled_name) {
|
||||||
|
push_uniq(mangled_names, mangled_name);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var tw = new TreeWalker(function(node, descend){
|
var tw = new TreeWalker(function(node, descend){
|
||||||
@@ -437,10 +457,6 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
|||||||
this.walk(tw);
|
this.walk(tw);
|
||||||
to_mangle.forEach(function(def){ def.mangle(options) });
|
to_mangle.forEach(function(def){ def.mangle(options) });
|
||||||
|
|
||||||
if (options.cache) {
|
|
||||||
options.cache.cname = this.cname;
|
|
||||||
}
|
|
||||||
|
|
||||||
function collect(symbol) {
|
function collect(symbol) {
|
||||||
if (!member(symbol.name, options.reserved)) {
|
if (!member(symbol.name, options.reserved)) {
|
||||||
to_mangle.push(symbol);
|
to_mangle.push(symbol);
|
||||||
@@ -448,59 +464,55 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Toplevel.DEFMETHOD("find_unique_prefix", function(options) {
|
AST_Toplevel.DEFMETHOD("find_colliding_names", function(options) {
|
||||||
var letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_";
|
|
||||||
var cache = options.cache && options.cache.props;
|
var cache = options.cache && options.cache.props;
|
||||||
var prefixes = Object.create(null);
|
var avoid = Object.create(null);
|
||||||
options.reserved.forEach(add_prefix);
|
options.reserved.forEach(to_avoid);
|
||||||
this.globals.each(add_def);
|
this.globals.each(add_def);
|
||||||
this.walk(new TreeWalker(function(node) {
|
this.walk(new TreeWalker(function(node) {
|
||||||
if (node instanceof AST_Scope) node.variables.each(add_def);
|
if (node instanceof AST_Scope) node.variables.each(add_def);
|
||||||
if (node instanceof AST_SymbolCatch) add_def(node.definition());
|
if (node instanceof AST_SymbolCatch) add_def(node.definition());
|
||||||
}));
|
}));
|
||||||
var prefix, i = 0;
|
return avoid;
|
||||||
do {
|
|
||||||
prefix = create_name(i++);
|
|
||||||
} while (prefixes[prefix]);
|
|
||||||
return prefix;
|
|
||||||
|
|
||||||
function add_prefix(name) {
|
function to_avoid(name) {
|
||||||
if (/[0-9]$/.test(name)) {
|
avoid[name] = true;
|
||||||
prefixes[name.replace(/[0-9]+$/, "")] = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function add_def(def) {
|
function add_def(def) {
|
||||||
var name = def.name;
|
var name = def.name;
|
||||||
if (def.global && cache && cache.has(name)) name = cache.get(name);
|
if (def.global && cache && cache.has(name)) name = cache.get(name);
|
||||||
else if (!def.unmangleable(options)) return;
|
else if (!def.unmangleable(options)) return;
|
||||||
add_prefix(name);
|
to_avoid(name);
|
||||||
}
|
|
||||||
|
|
||||||
function create_name(num) {
|
|
||||||
var name = "";
|
|
||||||
do {
|
|
||||||
name += letters[num % letters.length];
|
|
||||||
num = Math.floor(num / letters.length);
|
|
||||||
} while (num);
|
|
||||||
return name;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Toplevel.DEFMETHOD("expand_names", function(options) {
|
AST_Toplevel.DEFMETHOD("expand_names", function(options) {
|
||||||
|
base54.reset();
|
||||||
|
base54.sort();
|
||||||
options = this._default_mangler_options(options);
|
options = this._default_mangler_options(options);
|
||||||
var prefix = this.find_unique_prefix(options);
|
var avoid = this.find_colliding_names(options);
|
||||||
|
var cname = 0;
|
||||||
this.globals.each(rename);
|
this.globals.each(rename);
|
||||||
this.walk(new TreeWalker(function(node) {
|
this.walk(new TreeWalker(function(node) {
|
||||||
if (node instanceof AST_Scope) node.variables.each(rename);
|
if (node instanceof AST_Scope) node.variables.each(rename);
|
||||||
if (node instanceof AST_SymbolCatch) rename(node.definition());
|
if (node instanceof AST_SymbolCatch) rename(node.definition());
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
function next_name() {
|
||||||
|
var name;
|
||||||
|
do {
|
||||||
|
name = base54(cname++);
|
||||||
|
} while (avoid[name] || !is_identifier(name));
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
function rename(def) {
|
function rename(def) {
|
||||||
if (def.global || def.unmangleable(options)) return;
|
if (def.global && options.cache) return;
|
||||||
|
if (def.unmangleable(options)) return;
|
||||||
if (member(def.name, options.reserved)) return;
|
if (member(def.name, options.reserved)) return;
|
||||||
var d = def.redefined();
|
var d = def.redefined();
|
||||||
def.name = d ? d.name : prefix + def.id;
|
def.name = d ? d.name : next_name();
|
||||||
def.orig.forEach(function(sym) {
|
def.orig.forEach(function(sym) {
|
||||||
sym.name = def.name;
|
sym.name = def.name;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -303,6 +303,13 @@ Dictionary.prototype = {
|
|||||||
ret.push(f(this._values[i], i.substr(1)));
|
ret.push(f(this._values[i], i.substr(1)));
|
||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
|
clone: function() {
|
||||||
|
var ret = new Dictionary();
|
||||||
|
for (var i in this._values)
|
||||||
|
ret._values[i] = this._values[i];
|
||||||
|
ret._size = this._size;
|
||||||
|
return ret;
|
||||||
|
},
|
||||||
toObject: function() { return this._values }
|
toObject: function() { return this._values }
|
||||||
};
|
};
|
||||||
Dictionary.fromObject = function(obj) {
|
Dictionary.fromObject = function(obj) {
|
||||||
|
|||||||
17
package.json
17
package.json
@@ -4,20 +4,15 @@
|
|||||||
"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.3.0",
|
"version": "3.3.10",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
},
|
},
|
||||||
"maintainers": [
|
"maintainers": [
|
||||||
|
"Alex Lam <alexlamsl@gmail.com>",
|
||||||
"Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)"
|
"Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)"
|
||||||
],
|
],
|
||||||
"repository": {
|
"repository": "mishoo/UglifyJS2",
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/mishoo/UglifyJS2.git"
|
|
||||||
},
|
|
||||||
"bugs": {
|
|
||||||
"url": "https://github.com/mishoo/UglifyJS2/issues"
|
|
||||||
},
|
|
||||||
"main": "tools/node.js",
|
"main": "tools/node.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
"uglifyjs": "bin/uglifyjs"
|
"uglifyjs": "bin/uglifyjs"
|
||||||
@@ -29,13 +24,13 @@
|
|||||||
"LICENSE"
|
"LICENSE"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"commander": "~2.12.1",
|
"commander": "~2.14.1",
|
||||||
"source-map": "~0.6.1"
|
"source-map": "~0.6.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"acorn": "~5.2.1",
|
"acorn": "~5.4.1",
|
||||||
"mocha": "~3.5.1",
|
"mocha": "~3.5.1",
|
||||||
"semver": "~5.4.1"
|
"semver": "~5.5.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "node test/run-tests.js"
|
"test": "node test/run-tests.js"
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ var urls = [
|
|||||||
"http://builds.emberjs.com/tags/v2.11.0/ember.prod.js",
|
"http://builds.emberjs.com/tags/v2.11.0/ember.prod.js",
|
||||||
"https://cdn.jsdelivr.net/lodash/4.17.4/lodash.js",
|
"https://cdn.jsdelivr.net/lodash/4.17.4/lodash.js",
|
||||||
"https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.js",
|
"https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.js",
|
||||||
|
"https://raw.githubusercontent.com/kangax/html-minifier/v3.5.7/dist/htmlminifier.js",
|
||||||
];
|
];
|
||||||
var results = {};
|
var results = {};
|
||||||
var remaining = 2 * urls.length;
|
var remaining = 2 * urls.length;
|
||||||
|
|||||||
@@ -52,13 +52,8 @@ collapse_vars_side_effects_1: {
|
|||||||
console.log.bind(console)(s.charAt(i++), s.charAt(i++), s.charAt(i++), 7);
|
console.log.bind(console)(s.charAt(i++), s.charAt(i++), s.charAt(i++), 7);
|
||||||
}
|
}
|
||||||
function f2() {
|
function f2() {
|
||||||
var log = console.log.bind(console),
|
var s = "abcdef", i = 2;
|
||||||
s = "abcdef",
|
console.log.bind(console)(s.charAt(i++), 5, s.charAt(i++), s.charAt(i++), 7);
|
||||||
i = 2,
|
|
||||||
x = s.charAt(i++),
|
|
||||||
y = s.charAt(i++),
|
|
||||||
z = s.charAt(i++);
|
|
||||||
log(x, i, y, z, 7);
|
|
||||||
}
|
}
|
||||||
function f3() {
|
function f3() {
|
||||||
var s = "abcdef",
|
var s = "abcdef",
|
||||||
@@ -72,7 +67,7 @@ collapse_vars_side_effects_1: {
|
|||||||
var i = 10,
|
var i = 10,
|
||||||
x = i += 2,
|
x = i += 2,
|
||||||
y = i += 3;
|
y = i += 3;
|
||||||
console.log.bind(console)(x, i += 4, y, i);
|
console.log.bind(console)(x, i += 4, y, 19);
|
||||||
}
|
}
|
||||||
f1(), f2(), f3(), f4();
|
f1(), f2(), f3(), f4();
|
||||||
}
|
}
|
||||||
@@ -2197,6 +2192,7 @@ toplevel_single_reference: {
|
|||||||
unused_orig: {
|
unused_orig: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
|
dead_code: true,
|
||||||
passes: 2,
|
passes: 2,
|
||||||
reduce_funcs: true,
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
@@ -3878,10 +3874,9 @@ recursive_function_replacement: {
|
|||||||
console.log(f(c));
|
console.log(f(c));
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f(n) {
|
console.log(function n(o) {
|
||||||
return x(y(f(n)));
|
return x(y(n(o)));
|
||||||
}
|
}(c));
|
||||||
console.log(f(c));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4012,3 +4007,513 @@ replace_all_var: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cascade_statement: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f1(a, b) {
|
||||||
|
var c;
|
||||||
|
if (a)
|
||||||
|
return c = b, c || a;
|
||||||
|
else
|
||||||
|
c = a, c(b);
|
||||||
|
}
|
||||||
|
function f2(a, b) {
|
||||||
|
var c;
|
||||||
|
while (a)
|
||||||
|
c = b, a = c + b;
|
||||||
|
do
|
||||||
|
throw c = a + b, c;
|
||||||
|
while (c);
|
||||||
|
}
|
||||||
|
function f3(a, b) {
|
||||||
|
for (; a < b; a++)
|
||||||
|
if (c = a, c && b)
|
||||||
|
var c = (c = b(a), c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f1(a, b) {
|
||||||
|
var c;
|
||||||
|
if (a)
|
||||||
|
return (c = b) || a;
|
||||||
|
else
|
||||||
|
(c = a)(b);
|
||||||
|
}
|
||||||
|
function f2(a, b) {
|
||||||
|
var c;
|
||||||
|
while (a)
|
||||||
|
a = (c = b) + b;
|
||||||
|
do
|
||||||
|
throw c = a + b;
|
||||||
|
while (c);
|
||||||
|
}
|
||||||
|
function f3(a, b) {
|
||||||
|
for (; a < b; a++)
|
||||||
|
if ((c = a) && b)
|
||||||
|
var c = c = b(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cascade_forin: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
function f(b) {
|
||||||
|
return [ b, b, b ];
|
||||||
|
}
|
||||||
|
for (var c in a = console, f(a))
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
function f(b) {
|
||||||
|
return [ b, b, b ];
|
||||||
|
}
|
||||||
|
for (var c in f(a = console))
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"0",
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe_builtin: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
unsafe: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
var b = Math.abs(a);
|
||||||
|
return Math.pow(b, 2);
|
||||||
|
}
|
||||||
|
console.log(f(-1), f(2));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
return Math.pow(Math.abs(a), 2);
|
||||||
|
}
|
||||||
|
console.log(f(-1), f(2));
|
||||||
|
}
|
||||||
|
expect_stdout: "1 4"
|
||||||
|
}
|
||||||
|
|
||||||
|
return_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var log = console.log;
|
||||||
|
function f(b, c) {
|
||||||
|
var a = c;
|
||||||
|
if (b) return b;
|
||||||
|
log(a);
|
||||||
|
}
|
||||||
|
f(false, 1);
|
||||||
|
f(true, 2);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var log = console.log;
|
||||||
|
function f(b, c) {
|
||||||
|
if (b) return b;
|
||||||
|
log(c);
|
||||||
|
}
|
||||||
|
f(false, 1);
|
||||||
|
f(true, 2);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
return_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var log = console.log;
|
||||||
|
function f(b, c) {
|
||||||
|
var a = c();
|
||||||
|
if (b) return b;
|
||||||
|
log(a);
|
||||||
|
}
|
||||||
|
f(false, function() { return 1 });
|
||||||
|
f(true, function() { return 2 });
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var log = console.log;
|
||||||
|
function f(b, c) {
|
||||||
|
var a = c();
|
||||||
|
if (b) return b;
|
||||||
|
log(a);
|
||||||
|
}
|
||||||
|
f(false, function() { return 1 });
|
||||||
|
f(true, function() { return 2 });
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
return_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var log = console.log;
|
||||||
|
function f(b, c) {
|
||||||
|
var a = b <<= c;
|
||||||
|
if (b) return b;
|
||||||
|
log(a);
|
||||||
|
}
|
||||||
|
f(false, 1);
|
||||||
|
f(true, 2);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var log = console.log;
|
||||||
|
function f(b, c) {
|
||||||
|
var a = b <<= c;
|
||||||
|
if (b) return b;
|
||||||
|
log(a);
|
||||||
|
}
|
||||||
|
f(false, 1);
|
||||||
|
f(true, 2);
|
||||||
|
}
|
||||||
|
expect_stdout: "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
return_4: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "FAIL";
|
||||||
|
(function(b) {
|
||||||
|
a = "PASS";
|
||||||
|
return;
|
||||||
|
b(a);
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "FAIL";
|
||||||
|
(function(b) {
|
||||||
|
a = "PASS";
|
||||||
|
return;
|
||||||
|
b(a);
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2858: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var b;
|
||||||
|
(function() {
|
||||||
|
function f() {
|
||||||
|
a++;
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
var c = f();
|
||||||
|
var a = void 0;
|
||||||
|
c || (b = a);
|
||||||
|
})();
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var b;
|
||||||
|
(function() {
|
||||||
|
function f() {
|
||||||
|
a++;
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
var c = f();
|
||||||
|
var a = void 0;
|
||||||
|
c || (b = a);
|
||||||
|
})();
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
cond_branch_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f1(b, c) {
|
||||||
|
var log = console.log;
|
||||||
|
var a = ++c;
|
||||||
|
if (b) b++;
|
||||||
|
log(a, b);
|
||||||
|
}
|
||||||
|
function f2(b, c) {
|
||||||
|
var log = console.log;
|
||||||
|
var a = ++c;
|
||||||
|
b && b++;
|
||||||
|
log(a, b);
|
||||||
|
}
|
||||||
|
function f3(b, c) {
|
||||||
|
var log = console.log;
|
||||||
|
var a = ++c;
|
||||||
|
b ? b++ : b--;
|
||||||
|
log(a, b);
|
||||||
|
}
|
||||||
|
f1(1, 2);
|
||||||
|
f2(3, 4);
|
||||||
|
f3(5, 6);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f1(b, c) {
|
||||||
|
if (b) b++;
|
||||||
|
(0, console.log)(++c, b);
|
||||||
|
}
|
||||||
|
function f2(b, c) {
|
||||||
|
b && b++,
|
||||||
|
(0, console.log)(++c, b);
|
||||||
|
}
|
||||||
|
function f3(b, c) {
|
||||||
|
b ? b++ : b--,
|
||||||
|
(0, console.log)(++c, b);
|
||||||
|
}
|
||||||
|
f1(1, 2),
|
||||||
|
f2(3, 4),
|
||||||
|
f3(5, 6);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"3 2",
|
||||||
|
"5 4",
|
||||||
|
"7 6",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
cond_branch_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f1(b, c) {
|
||||||
|
var log = console.log;
|
||||||
|
var a = ++c;
|
||||||
|
if (b) b += a;
|
||||||
|
log(a, b);
|
||||||
|
}
|
||||||
|
function f2(b, c) {
|
||||||
|
var log = console.log;
|
||||||
|
var a = ++c;
|
||||||
|
b && (b += a);
|
||||||
|
log(a, b);
|
||||||
|
}
|
||||||
|
function f3(b, c) {
|
||||||
|
var log = console.log;
|
||||||
|
var a = ++c;
|
||||||
|
b ? b += a : b--;
|
||||||
|
log(a, b);
|
||||||
|
}
|
||||||
|
f1(1, 2);
|
||||||
|
f2(3, 4);
|
||||||
|
f3(5, 6);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f1(b, c) {
|
||||||
|
var a = ++c;
|
||||||
|
if (b) b += a;
|
||||||
|
(0, console.log)(a, b);
|
||||||
|
}
|
||||||
|
function f2(b, c) {
|
||||||
|
var a = ++c;
|
||||||
|
b && (b += a),
|
||||||
|
(0, console.log)(a, b);
|
||||||
|
}
|
||||||
|
function f3(b, c) {
|
||||||
|
var a = ++c;
|
||||||
|
b ? b += a : b--,
|
||||||
|
(0, console.log)(a, b);
|
||||||
|
}
|
||||||
|
f1(1, 2),
|
||||||
|
f2(3, 4),
|
||||||
|
f3(5, 6);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"3 4",
|
||||||
|
"5 8",
|
||||||
|
"7 12",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
cond_branch_switch: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var c = 0;
|
||||||
|
if (c = 1 + c, 0) switch (c = 1 + c) {
|
||||||
|
}
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c = 0;
|
||||||
|
if (c = 1 + c, 0) switch (c = 1 + c) {
|
||||||
|
}
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2873_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var b = 1, c = 0;
|
||||||
|
do {
|
||||||
|
c++;
|
||||||
|
if (!--b) break;
|
||||||
|
c = 1 + c;
|
||||||
|
} while (0);
|
||||||
|
console.log(b, c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var b = 1, c = 0;
|
||||||
|
do {
|
||||||
|
c++;
|
||||||
|
if (!--b) break;
|
||||||
|
c = 1 + c;
|
||||||
|
} while (0);
|
||||||
|
console.log(b, c);
|
||||||
|
}
|
||||||
|
expect_stdout: "0 1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2873_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var b = 1, c = 0;
|
||||||
|
do {
|
||||||
|
c++;
|
||||||
|
if (!--b) continue;
|
||||||
|
c = 1 + c;
|
||||||
|
} while (0);
|
||||||
|
console.log(b, c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var b = 1, c = 0;
|
||||||
|
do {
|
||||||
|
c++;
|
||||||
|
if (!--b) continue;
|
||||||
|
c = 1 + c;
|
||||||
|
} while (0);
|
||||||
|
console.log(b, c);
|
||||||
|
}
|
||||||
|
expect_stdout: "0 1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2878: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var c = 0;
|
||||||
|
(function (a, b) {
|
||||||
|
function f2() {
|
||||||
|
if (a) c++;
|
||||||
|
}
|
||||||
|
b = f2();
|
||||||
|
a = 1;
|
||||||
|
b && b.b;
|
||||||
|
f2();
|
||||||
|
})();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c = 0;
|
||||||
|
(function (a, b) {
|
||||||
|
function f2() {
|
||||||
|
if (a) c++;
|
||||||
|
}
|
||||||
|
b = f2(),
|
||||||
|
a = 1,
|
||||||
|
b && b.b,
|
||||||
|
f2();
|
||||||
|
})(),
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2891_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS", b;
|
||||||
|
try {
|
||||||
|
b = c.p = 0;
|
||||||
|
a = "FAIL";
|
||||||
|
b();
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "PASS", b;
|
||||||
|
try {
|
||||||
|
b = c.p = 0;
|
||||||
|
a = "FAIL";
|
||||||
|
b();
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2891_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
var a = "PASS", b;
|
||||||
|
try {
|
||||||
|
b = c = 0;
|
||||||
|
a = "FAIL";
|
||||||
|
b();
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
var a = "PASS", b;
|
||||||
|
try {
|
||||||
|
b = c = 0;
|
||||||
|
a = "FAIL";
|
||||||
|
b();
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|||||||
@@ -112,3 +112,206 @@ self_comparison_2: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "false true"
|
expect_stdout: "false true"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2857_1: {
|
||||||
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f1(a) {
|
||||||
|
a === undefined || a === null;
|
||||||
|
a === undefined || a !== null;
|
||||||
|
a !== undefined || a === null;
|
||||||
|
a !== undefined || a !== null;
|
||||||
|
a === undefined && a === null;
|
||||||
|
a === undefined && a !== null;
|
||||||
|
a !== undefined && a === null;
|
||||||
|
a !== undefined && a !== null;
|
||||||
|
}
|
||||||
|
function f2(a) {
|
||||||
|
a === null || a === undefined;
|
||||||
|
a === null || a !== undefined;
|
||||||
|
a !== null || a === undefined;
|
||||||
|
a !== null || a !== undefined;
|
||||||
|
a === null && a === undefined;
|
||||||
|
a === null && a !== undefined;
|
||||||
|
a !== null && a === undefined;
|
||||||
|
a !== null && a !== undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f1(a) {
|
||||||
|
null == a;
|
||||||
|
void 0 === a || null !== a;
|
||||||
|
void 0 !== a || null === a;
|
||||||
|
void 0 !== a || null !== a;
|
||||||
|
void 0 === a && null === a;
|
||||||
|
void 0 === a && null !== a;
|
||||||
|
void 0 !== a && null === a;
|
||||||
|
null != a;
|
||||||
|
}
|
||||||
|
function f2(a) {
|
||||||
|
null == a;
|
||||||
|
null === a || void 0 !== a;
|
||||||
|
null !== a || void 0 === a;
|
||||||
|
null !== a || void 0 !== a;
|
||||||
|
null === a && void 0 === a;
|
||||||
|
null === a && void 0 !== a;
|
||||||
|
null !== a && void 0 === a;
|
||||||
|
null != a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2857_2: {
|
||||||
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a, p) {
|
||||||
|
a === undefined || a === null || p;
|
||||||
|
a === undefined || a !== null || p;
|
||||||
|
a !== undefined || a === null || p;
|
||||||
|
a !== undefined || a !== null || p;
|
||||||
|
a === undefined && a === null || p;
|
||||||
|
a === undefined && a !== null || p;
|
||||||
|
a !== undefined && a === null || p;
|
||||||
|
a !== undefined && a !== null || p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a, p) {
|
||||||
|
null == a || p;
|
||||||
|
void 0 === a || null !== a || p;
|
||||||
|
void 0 !== a || null === a || p;
|
||||||
|
void 0 !== a || null !== a || p;
|
||||||
|
void 0 === a && null === a || p;
|
||||||
|
void 0 === a && null !== a || p;
|
||||||
|
void 0 !== a && null === a || p;
|
||||||
|
null != a || p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2857_3: {
|
||||||
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a, p) {
|
||||||
|
a === undefined || a === null && p;
|
||||||
|
a === undefined || a !== null && p;
|
||||||
|
a !== undefined || a === null && p;
|
||||||
|
a !== undefined || a !== null && p;
|
||||||
|
a === undefined && a === null && p;
|
||||||
|
a === undefined && a !== null && p;
|
||||||
|
a !== undefined && a === null && p;
|
||||||
|
a !== undefined && a !== null && p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a, p) {
|
||||||
|
void 0 === a || null === a && p;
|
||||||
|
void 0 === a || null !== a && p;
|
||||||
|
void 0 !== a || null === a && p;
|
||||||
|
void 0 !== a || null !== a && p;
|
||||||
|
void 0 === a && null === a && p;
|
||||||
|
void 0 === a && null !== a && p;
|
||||||
|
void 0 !== a && null === a && p;
|
||||||
|
null != a && p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2857_4: {
|
||||||
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a, p) {
|
||||||
|
p || a === undefined || a === null;
|
||||||
|
p || a === undefined || a !== null;
|
||||||
|
p || a !== undefined || a === null;
|
||||||
|
p || a !== undefined || a !== null;
|
||||||
|
p || a === undefined && a === null;
|
||||||
|
p || a === undefined && a !== null;
|
||||||
|
p || a !== undefined && a === null;
|
||||||
|
p || a !== undefined && a !== null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a, p) {
|
||||||
|
p || null == a;
|
||||||
|
p || void 0 === a || null !== a;
|
||||||
|
p || void 0 !== a || null === a;
|
||||||
|
p || void 0 !== a || null !== a;
|
||||||
|
p || void 0 === a && null === a;
|
||||||
|
p || void 0 === a && null !== a;
|
||||||
|
p || void 0 !== a && null === a;
|
||||||
|
p || null != a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2857_5: {
|
||||||
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a, p) {
|
||||||
|
p && a === undefined || a === null;
|
||||||
|
p && a === undefined || a !== null;
|
||||||
|
p && a !== undefined || a === null;
|
||||||
|
p && a !== undefined || a !== null;
|
||||||
|
p && a === undefined && a === null;
|
||||||
|
p && a === undefined && a !== null;
|
||||||
|
p && a !== undefined && a === null;
|
||||||
|
p && a !== undefined && a !== null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a, p) {
|
||||||
|
p && void 0 === a || null === a;
|
||||||
|
p && void 0 === a || null !== a;
|
||||||
|
p && void 0 !== a || null === a;
|
||||||
|
p && void 0 !== a || null !== a;
|
||||||
|
p && void 0 === a && null === a;
|
||||||
|
p && void 0 === a && null !== a;
|
||||||
|
p && void 0 !== a && null === a;
|
||||||
|
p && null != a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2857_6: {
|
||||||
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
if (({}).b === undefined || {}.b === null)
|
||||||
|
return a.b !== undefined && a.b !== null;
|
||||||
|
}
|
||||||
|
console.log(f({
|
||||||
|
a: [ null ],
|
||||||
|
get b() {
|
||||||
|
return this.a.shift();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
if (null == {}.b)
|
||||||
|
return void 0 !== a.b && null !== a.b;
|
||||||
|
}
|
||||||
|
console.log(f({
|
||||||
|
a: [ null ],
|
||||||
|
get b() {
|
||||||
|
return this.a.shift();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
expect_stdout: "true"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1203,3 +1203,67 @@ issue_2560: {
|
|||||||
"2",
|
"2",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hoist_decl: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
join_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
if (x()) {
|
||||||
|
var a;
|
||||||
|
y();
|
||||||
|
} else {
|
||||||
|
z();
|
||||||
|
var b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a, b;
|
||||||
|
x() ? y() : z();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
to_and_or: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var values = [
|
||||||
|
0,
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
"foo",
|
||||||
|
false,
|
||||||
|
-1 / 0,
|
||||||
|
void 0,
|
||||||
|
];
|
||||||
|
values.forEach(function(x) {
|
||||||
|
values.forEach(function(y) {
|
||||||
|
values.forEach(function(z) {
|
||||||
|
console.log(x ? y || z : z);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var values = [
|
||||||
|
0,
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
"foo",
|
||||||
|
false,
|
||||||
|
-1 / 0,
|
||||||
|
void 0,
|
||||||
|
];
|
||||||
|
values.forEach(function(x) {
|
||||||
|
values.forEach(function(y) {
|
||||||
|
values.forEach(function(z) {
|
||||||
|
console.log(x && y || z);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|||||||
@@ -62,46 +62,6 @@ dead_code_2_should_warn: {
|
|||||||
node_version: "<=4"
|
node_version: "<=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
dead_code_2_should_warn_strict: {
|
|
||||||
options = {
|
|
||||||
dead_code: true
|
|
||||||
};
|
|
||||||
input: {
|
|
||||||
"use strict";
|
|
||||||
function f() {
|
|
||||||
g();
|
|
||||||
x = 10;
|
|
||||||
throw new Error("foo");
|
|
||||||
// completely discarding the `if` would introduce some
|
|
||||||
// bugs. UglifyJS v1 doesn't deal with this issue; in v2
|
|
||||||
// we copy any declarations to the upper scope.
|
|
||||||
if (x) {
|
|
||||||
y();
|
|
||||||
var x;
|
|
||||||
function g(){};
|
|
||||||
// but nested declarations should not be kept.
|
|
||||||
(function(){
|
|
||||||
var q;
|
|
||||||
function y(){};
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
f();
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
"use strict";
|
|
||||||
function f() {
|
|
||||||
g();
|
|
||||||
x = 10;
|
|
||||||
throw new Error("foo");
|
|
||||||
var x;
|
|
||||||
}
|
|
||||||
f();
|
|
||||||
}
|
|
||||||
expect_stdout: true
|
|
||||||
node_version: ">=4"
|
|
||||||
}
|
|
||||||
|
|
||||||
dead_code_constant_boolean_should_warn_more: {
|
dead_code_constant_boolean_should_warn_more: {
|
||||||
options = {
|
options = {
|
||||||
dead_code : true,
|
dead_code : true,
|
||||||
@@ -137,42 +97,6 @@ dead_code_constant_boolean_should_warn_more: {
|
|||||||
node_version: "<=4"
|
node_version: "<=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
dead_code_constant_boolean_should_warn_more_strict: {
|
|
||||||
options = {
|
|
||||||
dead_code : true,
|
|
||||||
loops : true,
|
|
||||||
booleans : true,
|
|
||||||
conditionals : true,
|
|
||||||
evaluate : true,
|
|
||||||
side_effects : true,
|
|
||||||
};
|
|
||||||
input: {
|
|
||||||
"use strict";
|
|
||||||
while (!((foo && bar) || (x + "0"))) {
|
|
||||||
console.log("unreachable");
|
|
||||||
var foo;
|
|
||||||
function bar() {}
|
|
||||||
}
|
|
||||||
for (var x = 10, y; x && (y || x) && (!typeof x); ++x) {
|
|
||||||
asdf();
|
|
||||||
foo();
|
|
||||||
var moo;
|
|
||||||
}
|
|
||||||
bar();
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
"use strict";
|
|
||||||
var foo;
|
|
||||||
// nothing for the while
|
|
||||||
// as for the for, it should keep:
|
|
||||||
var moo;
|
|
||||||
var x = 10, y;
|
|
||||||
bar();
|
|
||||||
}
|
|
||||||
expect_stdout: true
|
|
||||||
node_version: ">=4"
|
|
||||||
}
|
|
||||||
|
|
||||||
try_catch_finally: {
|
try_catch_finally: {
|
||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
@@ -828,3 +752,168 @@ issue_2597: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2666: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
return a = {
|
||||||
|
p: function() {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
console.log(typeof f().p());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
return a = {
|
||||||
|
p: function() {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
console.log(typeof f().p());
|
||||||
|
}
|
||||||
|
expect_stdout: "object"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2692: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
reduce_vars: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
return a = g;
|
||||||
|
function g() {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(typeof f()());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
return a = g;
|
||||||
|
function g() {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(typeof f()());
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2701: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
inline: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
return a = function() {
|
||||||
|
return function() {
|
||||||
|
return a;
|
||||||
|
};
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
console.log(typeof f()());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
return a = function() {
|
||||||
|
return function() {
|
||||||
|
return a;
|
||||||
|
};
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
console.log(typeof f()());
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2749: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
inline: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 2, c = "PASS";
|
||||||
|
while (a--)
|
||||||
|
(function() {
|
||||||
|
return b ? c = "FAIL" : b = 1;
|
||||||
|
try {
|
||||||
|
} catch (b) {
|
||||||
|
var b;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 2, c = "PASS";
|
||||||
|
while (a--)
|
||||||
|
b = void 0, b ? c = "FAIL" : b = 1;
|
||||||
|
var b;
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe_builtin: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(!w).constructor(x);
|
||||||
|
Math.abs(y);
|
||||||
|
[ 1, 2, z ].valueOf();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
w, x;
|
||||||
|
y;
|
||||||
|
z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2860_1: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a) {
|
||||||
|
return a ^= 1;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a) {
|
||||||
|
return 1 ^ a;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2860_2: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 2,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a) {
|
||||||
|
return a ^= 1;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(1);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1413,3 +1413,309 @@ issue_2516_2: {
|
|||||||
Baz(2);
|
Baz(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defun_lambda_same_name: {
|
||||||
|
options = {
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(n) {
|
||||||
|
return n ? n * f(n - 1) : 1;
|
||||||
|
}
|
||||||
|
console.log(function f(n) {
|
||||||
|
return n ? n * f(n - 1) : 1;
|
||||||
|
}(5));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function f(n) {
|
||||||
|
return n ? n * f(n - 1) : 1;
|
||||||
|
}(5));
|
||||||
|
}
|
||||||
|
expect_stdout: "120"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2660_1: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 2;
|
||||||
|
function f(b) {
|
||||||
|
return b && f() || a--;
|
||||||
|
}
|
||||||
|
f(1);
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 2;
|
||||||
|
(function f(b) {
|
||||||
|
return b && f() || a--;
|
||||||
|
})(1);
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2660_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 1;
|
||||||
|
function f(b) {
|
||||||
|
b && f();
|
||||||
|
--a, a.toString();
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 1;
|
||||||
|
(function f(b) {
|
||||||
|
b && f(),
|
||||||
|
(--a).toString();
|
||||||
|
})(),
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2665: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
passes: 2,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
typeofs: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 1;
|
||||||
|
function g() {
|
||||||
|
a-- && g();
|
||||||
|
}
|
||||||
|
typeof h == "function" && h();
|
||||||
|
function h() {
|
||||||
|
typeof g == "function" && g();
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 1;
|
||||||
|
!function g() {
|
||||||
|
a-- && g();
|
||||||
|
}();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "-1"
|
||||||
|
}
|
||||||
|
|
||||||
|
double_assign_1: {
|
||||||
|
options = {
|
||||||
|
passes: 2,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f1() {
|
||||||
|
var a = {};
|
||||||
|
var a = [];
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
function f2() {
|
||||||
|
var a = {};
|
||||||
|
a = [];
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
function f3() {
|
||||||
|
a = {};
|
||||||
|
var a = [];
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
function f4(a) {
|
||||||
|
a = {};
|
||||||
|
a = [];
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
function f5(a) {
|
||||||
|
var a = {};
|
||||||
|
a = [];
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
function f6(a) {
|
||||||
|
a = {};
|
||||||
|
var a = [];
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
console.log(f1(), f2(), f3(), f4(), f5(), f6());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f1() {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
function f2() {
|
||||||
|
var a;
|
||||||
|
a = [];
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
function f3() {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
function f4(a) {
|
||||||
|
a = [];
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
function f5(a) {
|
||||||
|
a = [];
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
function f6(a) {
|
||||||
|
a = [];
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
console.log(f1(), f2(), f3(), f4(), f5(), f6());
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
double_assign_2: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
for (var i = 0; i < 2; i++)
|
||||||
|
a = void 0, a = {}, console.log(a);
|
||||||
|
var a;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
for (var i = 0; i < 2; i++)
|
||||||
|
void 0, a = {}, console.log(a);
|
||||||
|
var a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double_assign_3: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
for (var i = 0; i < 2; i++)
|
||||||
|
a = void 0, a = { a: a }, console.log(a);
|
||||||
|
var a;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
for (var i = 0; i < 2; i++)
|
||||||
|
a = void 0, a = { a: a }, console.log(a);
|
||||||
|
var a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cascade_drop_assign: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a, b = a = "PASS";
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var b = "PASS";
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
chained_3: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a, b) {
|
||||||
|
var c = a, c = b;
|
||||||
|
b++;
|
||||||
|
return c;
|
||||||
|
}(1, 2));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a, b) {
|
||||||
|
var c = b;
|
||||||
|
b++;
|
||||||
|
return c;
|
||||||
|
}(0, 2));
|
||||||
|
}
|
||||||
|
expect_stdout: "2"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2768: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "FAIL", c = 1;
|
||||||
|
var c = function(b) {
|
||||||
|
var d = b = a;
|
||||||
|
var e = --b + (d && (a = "PASS"));
|
||||||
|
}();
|
||||||
|
console.log(a, typeof c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "FAIL";
|
||||||
|
var c = (d = a, 0, void (d && (a = "PASS")));
|
||||||
|
var d;
|
||||||
|
console.log(a, typeof c);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2846: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a, b) {
|
||||||
|
var a = 0;
|
||||||
|
b && b(a);
|
||||||
|
return a++;
|
||||||
|
}
|
||||||
|
var c = f();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c = function(a, b) {
|
||||||
|
a = 0;
|
||||||
|
b && b(a);
|
||||||
|
return a++;
|
||||||
|
}();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: "0"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1194,6 +1194,9 @@ issue_2231_1: {
|
|||||||
console.log(Object.keys(void 0));
|
console.log(Object.keys(void 0));
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
|
expect_warnings: [
|
||||||
|
"WARN: Error evaluating Object.keys(void 0) [test/compress/evaluate.js:1191,20]",
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_2231_2: {
|
issue_2231_2: {
|
||||||
@@ -1208,6 +1211,23 @@ issue_2231_2: {
|
|||||||
console.log(Object.getOwnPropertyNames(null));
|
console.log(Object.getOwnPropertyNames(null));
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
|
expect_warnings: [
|
||||||
|
"WARN: Error evaluating Object.getOwnPropertyNames(null) [test/compress/evaluate.js:1208,20]",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2231_3: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(Object.keys({ foo: "bar" })[0]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("foo");
|
||||||
|
}
|
||||||
|
expect_stdout: "foo"
|
||||||
}
|
}
|
||||||
|
|
||||||
self_comparison_1: {
|
self_comparison_1: {
|
||||||
@@ -1330,13 +1350,82 @@ issue_2535_3: {
|
|||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
expect_warnings: [
|
expect_warnings: [
|
||||||
"WARN: Dropping side-effect-free && [test/compress/evaluate.js:1316,20]",
|
"WARN: Dropping side-effect-free && [test/compress/evaluate.js:1336,20]",
|
||||||
"WARN: Dropping side-effect-free && [test/compress/evaluate.js:1317,20]",
|
"WARN: Dropping side-effect-free && [test/compress/evaluate.js:1337,20]",
|
||||||
"WARN: Dropping side-effect-free && [test/compress/evaluate.js:1318,20]",
|
"WARN: Dropping side-effect-free && [test/compress/evaluate.js:1338,20]",
|
||||||
"WARN: Condition left of && always false [test/compress/evaluate.js:1318,20]",
|
"WARN: Condition left of && always false [test/compress/evaluate.js:1338,20]",
|
||||||
"WARN: Dropping side-effect-free || [test/compress/evaluate.js:1319,20]",
|
"WARN: Dropping side-effect-free || [test/compress/evaluate.js:1339,20]",
|
||||||
"WARN: Dropping side-effect-free || [test/compress/evaluate.js:1320,20]",
|
"WARN: Dropping side-effect-free || [test/compress/evaluate.js:1340,20]",
|
||||||
"WARN: Dropping side-effect-free || [test/compress/evaluate.js:1321,20]",
|
"WARN: Dropping side-effect-free || [test/compress/evaluate.js:1341,20]",
|
||||||
"WARN: Condition left of || always true [test/compress/evaluate.js:1321,20]",
|
"WARN: Condition left of || always true [test/compress/evaluate.js:1341,20]",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2822: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log([ function() {}, "PASS", "FAIL" ][1]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
string_case: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log("İ".toLowerCase().charCodeAt(0));
|
||||||
|
console.log("I".toLowerCase().charCodeAt(0));
|
||||||
|
console.log("Ş".toLowerCase().charCodeAt(0));
|
||||||
|
console.log("Ğ".toLowerCase().charCodeAt(0));
|
||||||
|
console.log("Ü".toLowerCase().charCodeAt(0));
|
||||||
|
console.log("Ö".toLowerCase().charCodeAt(0));
|
||||||
|
console.log("Ç".toLowerCase().charCodeAt(0));
|
||||||
|
console.log("i".toUpperCase().charCodeAt(0));
|
||||||
|
console.log("ı".toUpperCase().charCodeAt(0));
|
||||||
|
console.log("ş".toUpperCase().charCodeAt(0));
|
||||||
|
console.log("ğ".toUpperCase().charCodeAt(0));
|
||||||
|
console.log("ü".toUpperCase().charCodeAt(0));
|
||||||
|
console.log("ö".toUpperCase().charCodeAt(0));
|
||||||
|
console.log("ç".toUpperCase().charCodeAt(0));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(105);
|
||||||
|
console.log(105);
|
||||||
|
console.log(351);
|
||||||
|
console.log(287);
|
||||||
|
console.log(252);
|
||||||
|
console.log(246);
|
||||||
|
console.log(231);
|
||||||
|
console.log(73);
|
||||||
|
console.log(73);
|
||||||
|
console.log(350);
|
||||||
|
console.log(286);
|
||||||
|
console.log(220);
|
||||||
|
console.log(214);
|
||||||
|
console.log(199);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"105",
|
||||||
|
"105",
|
||||||
|
"351",
|
||||||
|
"287",
|
||||||
|
"252",
|
||||||
|
"246",
|
||||||
|
"231",
|
||||||
|
"73",
|
||||||
|
"73",
|
||||||
|
"350",
|
||||||
|
"286",
|
||||||
|
"220",
|
||||||
|
"214",
|
||||||
|
"199",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -214,51 +214,11 @@ hoist_funs: {
|
|||||||
node_version: "<=4"
|
node_version: "<=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
hoist_funs_strict: {
|
|
||||||
options = {
|
|
||||||
hoist_funs: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
"use strict";
|
|
||||||
console.log(1, typeof f, typeof g);
|
|
||||||
if (console.log(2, typeof f, typeof g))
|
|
||||||
console.log(3, typeof f, typeof g);
|
|
||||||
else {
|
|
||||||
console.log(4, typeof f, typeof g);
|
|
||||||
function f() {}
|
|
||||||
console.log(5, typeof f, typeof g);
|
|
||||||
}
|
|
||||||
function g() {}
|
|
||||||
console.log(6, typeof f, typeof g);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
"use strict";
|
|
||||||
function g() {}
|
|
||||||
console.log(1, typeof f, typeof g);
|
|
||||||
if (console.log(2, typeof f, typeof g))
|
|
||||||
console.log(3, typeof f, typeof g);
|
|
||||||
else {
|
|
||||||
console.log(4, typeof f, typeof g);
|
|
||||||
function f() {}
|
|
||||||
console.log(5, typeof f, typeof g);
|
|
||||||
}
|
|
||||||
console.log(6, typeof f, typeof g);
|
|
||||||
}
|
|
||||||
expect_stdout: [
|
|
||||||
"1 'undefined' 'function'",
|
|
||||||
"2 'undefined' 'function'",
|
|
||||||
"4 'function' 'function'",
|
|
||||||
"5 'function' 'function'",
|
|
||||||
"6 'undefined' 'function'",
|
|
||||||
]
|
|
||||||
node_version: ">=4"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_203: {
|
issue_203: {
|
||||||
options = {
|
options = {
|
||||||
keep_fargs: false,
|
keep_fargs: false,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
unsafe_Func: true,
|
unsafe_Function: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -800,12 +760,12 @@ issue_2601_1: {
|
|||||||
expect: {
|
expect: {
|
||||||
var a = "FAIL";
|
var a = "FAIL";
|
||||||
(function() {
|
(function() {
|
||||||
|
var b;
|
||||||
b = "foo",
|
b = "foo",
|
||||||
function(b) {
|
function(b) {
|
||||||
b && b();
|
b && b();
|
||||||
}(),
|
}(),
|
||||||
b && (a = "PASS");
|
b && (a = "PASS");
|
||||||
var b;
|
|
||||||
})(),
|
})(),
|
||||||
console.log(a);
|
console.log(a);
|
||||||
}
|
}
|
||||||
@@ -1285,7 +1245,7 @@ issue_2630_1: {
|
|||||||
expect: {
|
expect: {
|
||||||
var c = 0;
|
var c = 0;
|
||||||
(function() {
|
(function() {
|
||||||
while (c++, void (c = 1 + c));
|
while (void (c = 1 + ++c));
|
||||||
})(),
|
})(),
|
||||||
console.log(c);
|
console.log(c);
|
||||||
}
|
}
|
||||||
@@ -1299,6 +1259,7 @@ issue_2630_2: {
|
|||||||
passes: 2,
|
passes: 2,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
sequences: true,
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -1316,7 +1277,7 @@ issue_2630_2: {
|
|||||||
expect: {
|
expect: {
|
||||||
var c = 0;
|
var c = 0;
|
||||||
!function() {
|
!function() {
|
||||||
while (c += 1, void (c = 1 + c));
|
while (void (c = 1 + (c += 1)));
|
||||||
}(), console.log(c);
|
}(), console.log(c);
|
||||||
}
|
}
|
||||||
expect_stdout: "2"
|
expect_stdout: "2"
|
||||||
@@ -1345,11 +1306,10 @@ issue_2630_3: {
|
|||||||
expect: {
|
expect: {
|
||||||
var x = 2, a = 1;
|
var x = 2, a = 1;
|
||||||
(function() {
|
(function() {
|
||||||
function f1(a) {
|
(function f1(a) {
|
||||||
f2();
|
f2();
|
||||||
--x >= 0 && f1({});
|
--x >= 0 && f1({});
|
||||||
}
|
})(a++);
|
||||||
f1(a++);
|
|
||||||
function f2() {
|
function f2() {
|
||||||
a++;
|
a++;
|
||||||
}
|
}
|
||||||
@@ -1417,9 +1377,615 @@ issue_2630_5: {
|
|||||||
!function() {
|
!function() {
|
||||||
do {
|
do {
|
||||||
c *= 10;
|
c *= 10;
|
||||||
} while (c += 3, (c = 2 + c) < 100);
|
} while ((c = 2 + (c += 3)) < 100);
|
||||||
}();
|
}();
|
||||||
console.log(c);
|
console.log(c);
|
||||||
}
|
}
|
||||||
expect_stdout: "155"
|
expect_stdout: "155"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
recursive_inline_1: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
h();
|
||||||
|
}
|
||||||
|
function g(a) {
|
||||||
|
a();
|
||||||
|
}
|
||||||
|
function h(b) {
|
||||||
|
g();
|
||||||
|
if (b) x();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {}
|
||||||
|
}
|
||||||
|
|
||||||
|
recursive_inline_2: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(n) {
|
||||||
|
return n ? n * f(n - 1) : 1;
|
||||||
|
}
|
||||||
|
console.log(f(5));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function f(n) {
|
||||||
|
return n ? n * f(n - 1) : 1;
|
||||||
|
}(5));
|
||||||
|
}
|
||||||
|
expect_stdout: "120"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2657: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
console.log(function f() {
|
||||||
|
return h;
|
||||||
|
function g(b) {
|
||||||
|
return b || b();
|
||||||
|
}
|
||||||
|
function h(a) {
|
||||||
|
g(a);
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
}()(42));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
console.log(function(a) {
|
||||||
|
return b = a, b || b(), a;
|
||||||
|
var b;
|
||||||
|
}(42));
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2663_1: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
var i, o = {};
|
||||||
|
function createFn(j) {
|
||||||
|
return function() {
|
||||||
|
console.log(j);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
for (i in { a: 1, b: 2, c: 3 })
|
||||||
|
o[i] = createFn(i);
|
||||||
|
for (i in o)
|
||||||
|
o[i]();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
var i, o = {};
|
||||||
|
function createFn(j) {
|
||||||
|
return function() {
|
||||||
|
console.log(j);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
for (i in { a: 1, b: 2, c: 3 })
|
||||||
|
o[i] = createFn(i);
|
||||||
|
for (i in o)
|
||||||
|
o[i]();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"a",
|
||||||
|
"b",
|
||||||
|
"c",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2663_2: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
var i;
|
||||||
|
function fn(j) {
|
||||||
|
return function() {
|
||||||
|
console.log(j);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
for (i in { a: 1, b: 2, c: 3 })
|
||||||
|
fn(i);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
var i;
|
||||||
|
for (i in { a: 1, b: 2, c: 3 })
|
||||||
|
j = i, console.log(j);
|
||||||
|
var j;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"a",
|
||||||
|
"b",
|
||||||
|
"c",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2663_3: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function () {
|
||||||
|
var outputs = [
|
||||||
|
{ type: 0, target: null, eventName: "ngSubmit", propName: null },
|
||||||
|
{ type: 0, target: null, eventName: "submit", propName: null },
|
||||||
|
{ type: 0, target: null, eventName: "reset", propName: null },
|
||||||
|
];
|
||||||
|
function listenToElementOutputs(outputs) {
|
||||||
|
var handlers = [];
|
||||||
|
for (var i = 0; i < outputs.length; i++) {
|
||||||
|
var output = outputs[i];
|
||||||
|
var handleEventClosure = renderEventHandlerClosure(output.eventName);
|
||||||
|
handlers.push(handleEventClosure)
|
||||||
|
}
|
||||||
|
var target, name;
|
||||||
|
return handlers;
|
||||||
|
}
|
||||||
|
function renderEventHandlerClosure(eventName) {
|
||||||
|
return function () {
|
||||||
|
return console.log(eventName);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
listenToElementOutputs(outputs).forEach(function (handler) {
|
||||||
|
return handler()
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
function renderEventHandlerClosure(eventName) {
|
||||||
|
return function() {
|
||||||
|
return console.log(eventName);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
(function(outputs) {
|
||||||
|
var handlers = [];
|
||||||
|
for (var i = 0; i < outputs.length; i++) {
|
||||||
|
var output = outputs[i];
|
||||||
|
var handleEventClosure = renderEventHandlerClosure(output.eventName);
|
||||||
|
handlers.push(handleEventClosure);
|
||||||
|
}
|
||||||
|
return handlers;
|
||||||
|
})([ {
|
||||||
|
type: 0,
|
||||||
|
target: null,
|
||||||
|
eventName: "ngSubmit",
|
||||||
|
propName: null
|
||||||
|
}, {
|
||||||
|
type: 0,
|
||||||
|
target: null,
|
||||||
|
eventName: "submit",
|
||||||
|
propName: null
|
||||||
|
}, {
|
||||||
|
type: 0,
|
||||||
|
target: null,
|
||||||
|
eventName: "reset",
|
||||||
|
propName: null
|
||||||
|
} ]).forEach(function(handler) {
|
||||||
|
return handler();
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"ngSubmit",
|
||||||
|
"submit",
|
||||||
|
"reset",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
duplicate_argnames: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS";
|
||||||
|
function f(b, b, b) {
|
||||||
|
b && (a = "FAIL");
|
||||||
|
}
|
||||||
|
f(0, console);
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "PASS";
|
||||||
|
console, b && (a = "FAIL");
|
||||||
|
var b;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
loop_init_arg: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS";
|
||||||
|
for (var k in "12") (function (b) {
|
||||||
|
(b >>= 1) && (a = "FAIL"), b = 2;
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "PASS";
|
||||||
|
for (var k in "12")
|
||||||
|
b = void 0, (b >>= 1) && (a = "FAIL"), b = 2;
|
||||||
|
var b;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
inline_false: {
|
||||||
|
options = {
|
||||||
|
inline: false,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
console.log(1);
|
||||||
|
})();
|
||||||
|
(function(a) {
|
||||||
|
console.log(a);
|
||||||
|
})(2);
|
||||||
|
(function(b) {
|
||||||
|
var c = b;
|
||||||
|
console.log(c);
|
||||||
|
})(3);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
console.log(1);
|
||||||
|
})();
|
||||||
|
(function(a) {
|
||||||
|
console.log(a);
|
||||||
|
})(2);
|
||||||
|
(function(b) {
|
||||||
|
var c = b;
|
||||||
|
console.log(c);
|
||||||
|
})(3);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"3",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
inline_0: {
|
||||||
|
options = {
|
||||||
|
inline: 0,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
console.log(1);
|
||||||
|
})();
|
||||||
|
(function(a) {
|
||||||
|
console.log(a);
|
||||||
|
})(2);
|
||||||
|
(function(b) {
|
||||||
|
var c = b;
|
||||||
|
console.log(c);
|
||||||
|
})(3);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
console.log(1);
|
||||||
|
})();
|
||||||
|
(function(a) {
|
||||||
|
console.log(a);
|
||||||
|
})(2);
|
||||||
|
(function(b) {
|
||||||
|
var c = b;
|
||||||
|
console.log(c);
|
||||||
|
})(3);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"3",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
inline_1: {
|
||||||
|
options = {
|
||||||
|
inline: 1,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
console.log(1);
|
||||||
|
})();
|
||||||
|
(function(a) {
|
||||||
|
console.log(a);
|
||||||
|
})(2);
|
||||||
|
(function(b) {
|
||||||
|
var c = b;
|
||||||
|
console.log(c);
|
||||||
|
})(3);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(1);
|
||||||
|
(function(a) {
|
||||||
|
console.log(a);
|
||||||
|
})(2);
|
||||||
|
(function(b) {
|
||||||
|
var c = b;
|
||||||
|
console.log(c);
|
||||||
|
})(3);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"3",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
inline_2: {
|
||||||
|
options = {
|
||||||
|
inline: 2,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
console.log(1);
|
||||||
|
})();
|
||||||
|
(function(a) {
|
||||||
|
console.log(a);
|
||||||
|
})(2);
|
||||||
|
(function(b) {
|
||||||
|
var c = b;
|
||||||
|
console.log(c);
|
||||||
|
})(3);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(1);
|
||||||
|
a = 2, console.log(a);
|
||||||
|
var a;
|
||||||
|
(function(b) {
|
||||||
|
var c = b;
|
||||||
|
console.log(c);
|
||||||
|
})(3);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"3",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
inline_3: {
|
||||||
|
options = {
|
||||||
|
inline: 3,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
console.log(1);
|
||||||
|
})();
|
||||||
|
(function(a) {
|
||||||
|
console.log(a);
|
||||||
|
})(2);
|
||||||
|
(function(b) {
|
||||||
|
var c = b;
|
||||||
|
console.log(c);
|
||||||
|
})(3);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(1);
|
||||||
|
a = 2, console.log(a);
|
||||||
|
var a;
|
||||||
|
b = 3, c = b, console.log(c);
|
||||||
|
var b, c;
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"3",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
inline_true: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
console.log(1);
|
||||||
|
})();
|
||||||
|
(function(a) {
|
||||||
|
console.log(a);
|
||||||
|
})(2);
|
||||||
|
(function(b) {
|
||||||
|
var c = b;
|
||||||
|
console.log(c);
|
||||||
|
})(3);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(1);
|
||||||
|
a = 2, console.log(a);
|
||||||
|
var a;
|
||||||
|
b = 3, c = b, console.log(c);
|
||||||
|
var b, c;
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"3",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
use_before_init_in_loop: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS";
|
||||||
|
for (var b = 2; --b >= 0;) (function() {
|
||||||
|
var c = function() {
|
||||||
|
return 1;
|
||||||
|
}(c && (a = "FAIL"));
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "PASS";
|
||||||
|
for (var b = 2; --b >= 0;)
|
||||||
|
c = void 0, c = (c && (a = "FAIL"), 1);
|
||||||
|
var c;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
duplicate_arg_var: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(b) {
|
||||||
|
return b;
|
||||||
|
var b;
|
||||||
|
}("PASS"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log((b = "PASS", b));
|
||||||
|
var b;
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2737_1: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a) {
|
||||||
|
while (a());
|
||||||
|
})(function f() {
|
||||||
|
console.log(typeof f);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a) {
|
||||||
|
while (a());
|
||||||
|
})(function f() {
|
||||||
|
console.log(typeof f);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2737_2: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(bar) {
|
||||||
|
for (;bar(); ) break;
|
||||||
|
})(function qux() {
|
||||||
|
return console.log("PASS"), qux;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(bar) {
|
||||||
|
for (;bar(); ) break;
|
||||||
|
})(function qux() {
|
||||||
|
return console.log("PASS"), qux;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2783: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
if_return: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
return g;
|
||||||
|
function f(a) {
|
||||||
|
var b = a.b;
|
||||||
|
if (b) return b;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
function g(o, i) {
|
||||||
|
while (i--) {
|
||||||
|
console.log(f(o));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})()({ b: "PASS" }, 1);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
return function(o,i) {
|
||||||
|
while (i--) console.log(f(o));
|
||||||
|
};
|
||||||
|
function f(a) {
|
||||||
|
var b = a.b;
|
||||||
|
return b || a;
|
||||||
|
}
|
||||||
|
})()({ b: "PASS" },1);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -664,3 +664,25 @@ issue_2519: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "5.5"
|
expect_stdout: "5.5"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
undefined_key: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
hoist_props: true,
|
||||||
|
join_vars: true,
|
||||||
|
passes: 4,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a, o = {};
|
||||||
|
o[a] = 1;
|
||||||
|
o.b = 2;
|
||||||
|
console.log(o[a] + o.b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(3);
|
||||||
|
}
|
||||||
|
expect_stdout: "3"
|
||||||
|
}
|
||||||
|
|||||||
@@ -326,3 +326,73 @@ issue_512: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if_var_return: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
if_return: true,
|
||||||
|
join_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
var a;
|
||||||
|
return;
|
||||||
|
var b;
|
||||||
|
}
|
||||||
|
function g() {
|
||||||
|
var a;
|
||||||
|
if (u()) {
|
||||||
|
var b;
|
||||||
|
return v();
|
||||||
|
var c;
|
||||||
|
}
|
||||||
|
var d;
|
||||||
|
if (w()) {
|
||||||
|
var e;
|
||||||
|
return x();
|
||||||
|
var f;
|
||||||
|
} else {
|
||||||
|
var g;
|
||||||
|
y();
|
||||||
|
var h;
|
||||||
|
}
|
||||||
|
var i;
|
||||||
|
z();
|
||||||
|
var j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
var a, b;
|
||||||
|
}
|
||||||
|
function g() {
|
||||||
|
var a, b, c, d, e, f, g, h, i, j;
|
||||||
|
return u() ? v() : w() ? x() : (y(), z(), void 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if_if_return_return: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a, b) {
|
||||||
|
if (a) {
|
||||||
|
if (b)
|
||||||
|
return b;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a, b) {
|
||||||
|
if (a)
|
||||||
|
return b || void 0;
|
||||||
|
g();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ unsafe_undefined: {
|
|||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
if_return: true,
|
if_return: true,
|
||||||
unsafe: true
|
unsafe_undefined: true,
|
||||||
}
|
}
|
||||||
mangle = {}
|
mangle = {}
|
||||||
input: {
|
input: {
|
||||||
@@ -30,7 +30,7 @@ keep_fnames: {
|
|||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
if_return: true,
|
if_return: true,
|
||||||
unsafe: true
|
unsafe_undefined: true,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
keep_fnames: true
|
keep_fnames: true
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ unsafe_undefined: {
|
|||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
if_return: true,
|
if_return: true,
|
||||||
unsafe: true,
|
unsafe_undefined: true,
|
||||||
}
|
}
|
||||||
mangle = {}
|
mangle = {}
|
||||||
input: {
|
input: {
|
||||||
|
|||||||
@@ -84,12 +84,12 @@ numeric_literal: {
|
|||||||
' 0: 0,',
|
' 0: 0,',
|
||||||
' "-0": 1,',
|
' "-0": 1,',
|
||||||
' 42: 2,',
|
' 42: 2,',
|
||||||
' "42": 3,',
|
' 42: 3,',
|
||||||
' 37: 4,',
|
' 37: 4,',
|
||||||
' o: 5,',
|
' o: 5,',
|
||||||
' 1e42: 6,',
|
' 1e42: 6,',
|
||||||
' b: 7,',
|
' b: 7,',
|
||||||
' "1e+42": 8',
|
' 1e42: 8',
|
||||||
'};',
|
'};',
|
||||||
'',
|
'',
|
||||||
'console.log(obj[-0], obj[-""], obj["-0"]);',
|
'console.log(obj[-0], obj[-""], obj["-0"]);',
|
||||||
|
|||||||
33
test/compress/issue-2652.js
Normal file
33
test/compress/issue-2652.js
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
insert_semicolon: {
|
||||||
|
beautify = {
|
||||||
|
beautify: true,
|
||||||
|
comments: "all",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a
|
||||||
|
/* foo */ var b
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"var a",
|
||||||
|
"/* foo */;",
|
||||||
|
"",
|
||||||
|
"var b;",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
unary_postfix: {
|
||||||
|
beautify = {
|
||||||
|
beautify: true,
|
||||||
|
comments: "all",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
a
|
||||||
|
/* foo */++b
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"a",
|
||||||
|
"/* foo */;",
|
||||||
|
"",
|
||||||
|
"++b;",
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -64,3 +64,27 @@ strings_concat: {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
regexp: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
RegExp("foo");
|
||||||
|
RegExp("bar", "ig");
|
||||||
|
RegExp(foo);
|
||||||
|
RegExp("bar", ig);
|
||||||
|
RegExp("should", "fail");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
/foo/;
|
||||||
|
/bar/ig;
|
||||||
|
RegExp(foo);
|
||||||
|
RegExp("bar", ig);
|
||||||
|
RegExp("should", "fail");
|
||||||
|
}
|
||||||
|
expect_warnings: [
|
||||||
|
'WARN: Error converting RegExp("should","fail") [test/compress/issue-269.js:78,2]',
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
32
test/compress/issue-2719.js
Normal file
32
test/compress/issue-2719.js
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
warn: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 2,
|
||||||
|
properties: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
return g();
|
||||||
|
}
|
||||||
|
function g() {
|
||||||
|
return g["call" + "er"].arguments;
|
||||||
|
}
|
||||||
|
// 3
|
||||||
|
console.log(f(1, 2, 3).length);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
// TypeError: Cannot read property 'arguments' of null
|
||||||
|
console.log(function g() {
|
||||||
|
return g.caller.arguments;
|
||||||
|
}().length);
|
||||||
|
}
|
||||||
|
expect_warnings: [
|
||||||
|
"WARN: Function.protoype.caller not supported [test/compress/issue-2719.js:17,19]",
|
||||||
|
"WARN: Function.protoype.arguments not supported [test/compress/issue-2719.js:17,19]",
|
||||||
|
]
|
||||||
|
}
|
||||||
37
test/compress/issue-2871.js
Normal file
37
test/compress/issue-2871.js
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
comparison_with_undefined: {
|
||||||
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
a == undefined;
|
||||||
|
a != undefined;
|
||||||
|
a === undefined;
|
||||||
|
a !== undefined;
|
||||||
|
|
||||||
|
undefined == a;
|
||||||
|
undefined != a;
|
||||||
|
undefined === a;
|
||||||
|
undefined !== a;
|
||||||
|
|
||||||
|
void 0 == a;
|
||||||
|
void 0 != a;
|
||||||
|
void 0 === a;
|
||||||
|
void 0 !== a;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
null == a;
|
||||||
|
null != a;
|
||||||
|
void 0 === a;
|
||||||
|
void 0 !== a;
|
||||||
|
|
||||||
|
null == a;
|
||||||
|
null != a;
|
||||||
|
void 0 === a;
|
||||||
|
void 0 !== a;
|
||||||
|
|
||||||
|
null == a;
|
||||||
|
null != a;
|
||||||
|
void 0 === a;
|
||||||
|
void 0 !== a;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -492,3 +492,116 @@ dead_code_condition: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "1"
|
expect_stdout: "1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2740_1: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
loops: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
for (; ; ) break;
|
||||||
|
for (a(); ; ) break;
|
||||||
|
for (; b(); ) break;
|
||||||
|
for (c(); d(); ) break;
|
||||||
|
for (; ; e()) break;
|
||||||
|
for (f(); ; g()) break;
|
||||||
|
for (; h(); i()) break;
|
||||||
|
for (j(); k(); l()) break;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
a();
|
||||||
|
b();
|
||||||
|
c();
|
||||||
|
d();
|
||||||
|
f();
|
||||||
|
h();
|
||||||
|
j();
|
||||||
|
k();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2740_2: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
loops: true,
|
||||||
|
passes: 2,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
L1: while (x()) {
|
||||||
|
break L1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
x();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2740_3: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
loops: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
L1: for (var x = 0; x < 3; x++) {
|
||||||
|
L2: for (var y = 0; y < 2; y++) {
|
||||||
|
break L1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(x, y);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
L1: for (var x = 0; x < 3; x++)
|
||||||
|
for (var y = 0; y < 2; y++)
|
||||||
|
break L1;
|
||||||
|
console.log(x, y);
|
||||||
|
}
|
||||||
|
expect_stdout: "0 0"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2740_4: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
loops: true,
|
||||||
|
passes: 2,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
L1: for (var x = 0; x < 3; x++) {
|
||||||
|
L2: for (var y = 0; y < 2; y++) {
|
||||||
|
break L2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(x, y);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
for (var x = 0; x < 3; x++) {
|
||||||
|
var y = 0;
|
||||||
|
y < 2;
|
||||||
|
}
|
||||||
|
console.log(x, y);
|
||||||
|
}
|
||||||
|
expect_stdout: "3 0"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2740_5: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
loops: true,
|
||||||
|
passes: 2,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
L1: for (var x = 0; x < 3; x++) {
|
||||||
|
break L1;
|
||||||
|
L2: for (var y = 0; y < 2; y++) {
|
||||||
|
break L2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(x, y);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var x = 0;
|
||||||
|
x < 3;
|
||||||
|
var y;
|
||||||
|
console.log(x,y);
|
||||||
|
}
|
||||||
|
expect_stdout: "0 undefined"
|
||||||
|
}
|
||||||
|
|||||||
@@ -567,16 +567,41 @@ native_prototype: {
|
|||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
Array.prototype.splice.apply(a, [1, 2, b, c]);
|
Array.prototype.splice.apply(a, [1, 2, b, c]);
|
||||||
|
Function.prototype.call.apply(console.log, console, [ "foo" ]);
|
||||||
|
Number.prototype.toFixed.call(Math.PI, 2);
|
||||||
Object.prototype.hasOwnProperty.call(d, "foo");
|
Object.prototype.hasOwnProperty.call(d, "foo");
|
||||||
|
RegExp.prototype.test.call(/foo/, "bar");
|
||||||
String.prototype.indexOf.call(e, "bar");
|
String.prototype.indexOf.call(e, "bar");
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
[].splice.apply(a, [1, 2, b, c]);
|
[].splice.apply(a, [1, 2, b, c]);
|
||||||
|
(function() {}).call.apply(console.log, console, [ "foo" ]);
|
||||||
|
0..toFixed.call(Math.PI, 2);
|
||||||
({}).hasOwnProperty.call(d, "foo");
|
({}).hasOwnProperty.call(d, "foo");
|
||||||
|
/t/.test.call(/foo/, "bar");
|
||||||
"".indexOf.call(e, "bar");
|
"".indexOf.call(e, "bar");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
native_prototype_lhs: {
|
||||||
|
options = {
|
||||||
|
unsafe_proto: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
Function.prototype.bar = "PASS";
|
||||||
|
return function() {};
|
||||||
|
}().bar);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
Function.prototype.bar = "PASS";
|
||||||
|
return function() {};
|
||||||
|
}().bar);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
accessor_boolean: {
|
accessor_boolean: {
|
||||||
input: {
|
input: {
|
||||||
var a = 1;
|
var a = 1;
|
||||||
@@ -1094,3 +1119,472 @@ const_prop_assign_pure: {
|
|||||||
x();
|
x();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
join_object_assignments_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
join_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
var x = {
|
||||||
|
a: 1,
|
||||||
|
c: (console.log("c"), "C"),
|
||||||
|
};
|
||||||
|
x.b = 2;
|
||||||
|
x[3] = function() {
|
||||||
|
console.log(x);
|
||||||
|
},
|
||||||
|
x["a"] = /foo/,
|
||||||
|
x.bar = x;
|
||||||
|
return x;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
var x = {
|
||||||
|
a: 1,
|
||||||
|
c: (console.log("c"), "C"),
|
||||||
|
b: 2,
|
||||||
|
3: function() {
|
||||||
|
console.log(x);
|
||||||
|
},
|
||||||
|
a: /foo/,
|
||||||
|
};
|
||||||
|
x.bar = x;
|
||||||
|
return x;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
join_object_assignments_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
hoist_props: true,
|
||||||
|
join_vars: true,
|
||||||
|
passes: 3,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
foo: 1,
|
||||||
|
};
|
||||||
|
o.bar = 2;
|
||||||
|
o.baz = 3;
|
||||||
|
console.log(o.foo, o.bar + o.bar, o.foo * o.bar * o.baz);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(1, 4, 6);
|
||||||
|
}
|
||||||
|
expect_stdout: "1 4 6"
|
||||||
|
}
|
||||||
|
|
||||||
|
join_object_assignments_3: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
join_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
var o = {
|
||||||
|
a: "PASS",
|
||||||
|
}, a = o.a;
|
||||||
|
o.a = "FAIL";
|
||||||
|
return a;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
var o = {
|
||||||
|
a: "PASS",
|
||||||
|
}, a = o.a;
|
||||||
|
o.a = "FAIL";
|
||||||
|
return a;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
join_object_assignments_return_1: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
var o = {
|
||||||
|
p: 3
|
||||||
|
};
|
||||||
|
return o.q = "foo";
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
var o = {
|
||||||
|
p: 3,
|
||||||
|
q: "foo"
|
||||||
|
};
|
||||||
|
return o.q;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "foo"
|
||||||
|
}
|
||||||
|
|
||||||
|
join_object_assignments_return_2: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
var o = {
|
||||||
|
p: 3
|
||||||
|
};
|
||||||
|
return o.q = /foo/,
|
||||||
|
o.r = "bar";
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
var o = {
|
||||||
|
p: 3,
|
||||||
|
q: /foo/,
|
||||||
|
r: "bar"
|
||||||
|
};
|
||||||
|
return o.r;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "bar"
|
||||||
|
}
|
||||||
|
|
||||||
|
join_object_assignments_return_3: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
var o = {
|
||||||
|
p: 3
|
||||||
|
};
|
||||||
|
return o.q = "foo",
|
||||||
|
o.p += "",
|
||||||
|
console.log(o.q),
|
||||||
|
o.p;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
var o = {
|
||||||
|
p: 3,
|
||||||
|
q: "foo"
|
||||||
|
};
|
||||||
|
return o.p += "",
|
||||||
|
console.log(o.q),
|
||||||
|
o.p;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"foo",
|
||||||
|
"3",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
join_object_assignments_for: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
var o = {
|
||||||
|
p: 3
|
||||||
|
};
|
||||||
|
for (o.q = "foo"; console.log(o.q););
|
||||||
|
return o.p;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
for (var o = {
|
||||||
|
p: 3,
|
||||||
|
q: "foo"
|
||||||
|
}; console.log(o.q););
|
||||||
|
return o.p;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"foo",
|
||||||
|
"3",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
join_object_assignments_if: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
var o = {};
|
||||||
|
if (o.a = "PASS") return o.a;
|
||||||
|
}())
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
var o = { a: "PASS" };
|
||||||
|
if (o.a) return o.a;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
join_object_assignments_forin: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
var o = {};
|
||||||
|
for (var a in o.a = "PASS", o)
|
||||||
|
return o[a];
|
||||||
|
}())
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
var o = { a: "PASS" };
|
||||||
|
for (var a in o)
|
||||||
|
return o[a];
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
join_object_assignments_negative: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
join_vars: true,
|
||||||
|
properties: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {};
|
||||||
|
o[0] = 0;
|
||||||
|
o[-0] = 1;
|
||||||
|
o[-1] = 2;
|
||||||
|
console.log(o[0], o[-0], o[-1]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
0: 0,
|
||||||
|
0: 1,
|
||||||
|
"-1": 2
|
||||||
|
};
|
||||||
|
console.log(o[0], o[-0], o[-1]);
|
||||||
|
}
|
||||||
|
expect_stdout: "1 1 2"
|
||||||
|
}
|
||||||
|
|
||||||
|
join_object_assignments_NaN_1: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {};
|
||||||
|
o[NaN] = 1;
|
||||||
|
o[0/0] = 2;
|
||||||
|
console.log(o[NaN], o[NaN]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {};
|
||||||
|
o[NaN] = 1;
|
||||||
|
o[0/0] = 2;
|
||||||
|
console.log(o[NaN], o[NaN]);
|
||||||
|
}
|
||||||
|
expect_stdout: "2 2"
|
||||||
|
}
|
||||||
|
|
||||||
|
join_object_assignments_NaN_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
join_vars: true,
|
||||||
|
properties: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {};
|
||||||
|
o[NaN] = 1;
|
||||||
|
o[0/0] = 2;
|
||||||
|
console.log(o[NaN], o[NaN]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
NaN: 1,
|
||||||
|
NaN: 2
|
||||||
|
};
|
||||||
|
console.log(o.NaN, o.NaN);
|
||||||
|
}
|
||||||
|
expect_stdout: "2 2"
|
||||||
|
}
|
||||||
|
|
||||||
|
join_object_assignments_null_0: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {};
|
||||||
|
o[null] = 1;
|
||||||
|
console.log(o[null]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {};
|
||||||
|
o[null] = 1;
|
||||||
|
console.log(o[null]);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
join_object_assignments_null_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
join_vars: true,
|
||||||
|
properties: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {};
|
||||||
|
o[null] = 1;
|
||||||
|
console.log(o[null]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
null: 1
|
||||||
|
};
|
||||||
|
console.log(o.null);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
join_object_assignments_void_0: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
join_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {};
|
||||||
|
o[void 0] = 1;
|
||||||
|
console.log(o[void 0]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
undefined: 1
|
||||||
|
};
|
||||||
|
console.log(o[void 0]);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
join_object_assignments_undefined_1: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {};
|
||||||
|
o[undefined] = 1;
|
||||||
|
console.log(o[undefined]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {};
|
||||||
|
o[void 0] = 1;
|
||||||
|
console.log(o[void 0]);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
join_object_assignments_undefined_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
join_vars: true,
|
||||||
|
properties: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {};
|
||||||
|
o[undefined] = 1;
|
||||||
|
console.log(o[undefined]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
undefined : 1
|
||||||
|
};
|
||||||
|
console.log(o[void 0]);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
join_object_assignments_Infinity: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
join_vars: true,
|
||||||
|
properties: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {};
|
||||||
|
o[Infinity] = 1;
|
||||||
|
o[1/0] = 2;
|
||||||
|
o[-Infinity] = 3;
|
||||||
|
o[-1/0] = 4;
|
||||||
|
console.log(o[Infinity], o[1/0], o[-Infinity], o[-1/0]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
Infinity: 1,
|
||||||
|
Infinity: 2,
|
||||||
|
"-Infinity": 3,
|
||||||
|
"-Infinity": 4
|
||||||
|
};
|
||||||
|
console.log(o[1/0], o[1/0], o[-1/0], o[-1/0]);
|
||||||
|
}
|
||||||
|
expect_stdout: "2 2 4 4"
|
||||||
|
}
|
||||||
|
|
||||||
|
join_object_assignments_regex: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
join_vars: true,
|
||||||
|
properties: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {};
|
||||||
|
o[/rx/] = 1;
|
||||||
|
console.log(o[/rx/]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
"/rx/": 1
|
||||||
|
};
|
||||||
|
console.log(o[/rx/]);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2816: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
var o = {
|
||||||
|
a: 1
|
||||||
|
};
|
||||||
|
o.b = 2;
|
||||||
|
o.a = 3;
|
||||||
|
o.c = 4;
|
||||||
|
console.log(o.a, o.b, o.c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
var o = {
|
||||||
|
a: 1,
|
||||||
|
b: 2
|
||||||
|
};
|
||||||
|
o.a = 3;
|
||||||
|
o.c = 4;
|
||||||
|
console.log(o.a, o.b, o.c);
|
||||||
|
}
|
||||||
|
expect_stdout: "3 2 4"
|
||||||
|
}
|
||||||
|
|||||||
@@ -414,3 +414,124 @@ issue_2638: {
|
|||||||
"/* */(a()||b())(c(),d());",
|
"/* */(a()||b())(c(),d());",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2705_1: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
comments: "all",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
/*@__PURE__*/ new a();
|
||||||
|
/*@__PURE__*/ (new b());
|
||||||
|
new (/*@__PURE__*/ c)();
|
||||||
|
(/*@__PURE__*/ new d());
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"new/* */c;",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2705_2: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
comments: "all",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
/*@__PURE__*/ new a(1)(2)(3);
|
||||||
|
/*@__PURE__*/ new (b(1))(2)(3);
|
||||||
|
/*@__PURE__*/ new (c(1)(2))(3);
|
||||||
|
/*@__PURE__*/ new (d(1)(2)(3));
|
||||||
|
new (/*@__PURE__*/ e)(1)(2)(3);
|
||||||
|
(/*@__PURE__*/ new f(1))(2)(3);
|
||||||
|
(/*@__PURE__*/ new g(1)(2))(3);
|
||||||
|
(/*@__PURE__*/ new h(1)(2)(3));
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"new/* */e(1)(2)(3);",
|
||||||
|
"/* */new f(1)(2)(3);",
|
||||||
|
"/* */new g(1)(2)(3);",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2705_3: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
comments: "all",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
/*@__PURE__*/ new a.x(1).y(2).z(3);
|
||||||
|
/*@__PURE__*/ new (b.x)(1).y(2).z(3);
|
||||||
|
/*@__PURE__*/ new (c.x(1)).y(2).z(3);
|
||||||
|
/*@__PURE__*/ new (d.x(1).y)(2).z(3);
|
||||||
|
/*@__PURE__*/ new (e.x(1).y(2)).z(3);
|
||||||
|
/*@__PURE__*/ new (f.x(1).y(2).z)(3);
|
||||||
|
/*@__PURE__*/ new (g.x(1).y(2).z(3));
|
||||||
|
new (/*@__PURE__*/ h).x(1).y(2).z(3);
|
||||||
|
/* */ new (/*@__PURE__*/ i.x)(1).y(2).z(3);
|
||||||
|
(/*@__PURE__*/ new j.x(1)).y(2).z(3);
|
||||||
|
(/*@__PURE__*/ new k.x(1).y)(2).z(3);
|
||||||
|
(/*@__PURE__*/ new l.x(1).y(2)).z(3);
|
||||||
|
(/*@__PURE__*/ new m.x(1).y(2).z)(3);
|
||||||
|
(/*@__PURE__*/ new n.x(1).y(2).z(3));
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"new/* */h.x(1).y(2).z(3);",
|
||||||
|
"/* */new/* */i.x(1).y(2).z(3);",
|
||||||
|
"/* */new j.x(1).y(2).z(3);",
|
||||||
|
"/* */new k.x(1).y(2).z(3);",
|
||||||
|
"/* */new l.x(1).y(2).z(3);",
|
||||||
|
"/* */new m.x(1).y(2).z(3);",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2705_4: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(/*@__PURE__*/ new x(), y());
|
||||||
|
(w(), /*@__PURE__*/ new x(), y());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
y();
|
||||||
|
w(), y();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2705_5: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
[ /*@__PURE__*/ new x() ];
|
||||||
|
[ /*@__PURE__*/ new x(), y() ];
|
||||||
|
[ w(), /*@__PURE__*/ new x(), y() ];
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
y();
|
||||||
|
w(), y();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2705_6: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
comments: "all",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
/*@__PURE__*/new (g() || h())(x(), y());
|
||||||
|
/* */ new (/*@__PURE__*/ (a() || b()))(c(), d());
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"/* */x(),y();",
|
||||||
|
"/* */new(/* */a()||b())(c(),d());",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
@@ -348,6 +348,57 @@ set_immutable_4: {
|
|||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set_immutable_5: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
evaluate: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: 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 += "";
|
||||||
|
1..foo ? console.log("FAIL") : console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
set_immutable_6: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
evaluate: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 1;
|
||||||
|
a.foo += "";
|
||||||
|
if (a.foo) console.log("FAIL");
|
||||||
|
else console.log("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
1..foo ? console.log("FAIL") : console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
set_mutable_1: {
|
set_mutable_1: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
@@ -611,3 +662,62 @@ issue_2313_6: {
|
|||||||
x();
|
x();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2678: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 1, c = "FAIL";
|
||||||
|
(function f() {
|
||||||
|
(a-- && f()).p;
|
||||||
|
return {
|
||||||
|
get p() {
|
||||||
|
c = "PASS";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 1, c = "FAIL";
|
||||||
|
(function f() {
|
||||||
|
(a-- && f()).p;
|
||||||
|
return {
|
||||||
|
get p() {
|
||||||
|
c = "PASS";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2838: {
|
||||||
|
options = {
|
||||||
|
pure_getters: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a, b) {
|
||||||
|
(a || b).c = "PASS";
|
||||||
|
(function() {
|
||||||
|
return f(a, b);
|
||||||
|
}).prototype.foo = "bar";
|
||||||
|
}
|
||||||
|
var o = {};
|
||||||
|
f(null, o);
|
||||||
|
console.log(o.c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a, b) {
|
||||||
|
(a || b).c = "PASS";
|
||||||
|
}
|
||||||
|
var o = {};
|
||||||
|
f(null, o);
|
||||||
|
console.log(o.c);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -76,14 +76,12 @@ modified: {
|
|||||||
console.log(a + 1);
|
console.log(a + 1);
|
||||||
console.log(b + 1);
|
console.log(b + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
function f1() {
|
function f1() {
|
||||||
var a = 1, b = 2;
|
var a = 1, b = 2;
|
||||||
--b;
|
--b;
|
||||||
console.log(a + 1);
|
console.log(a + 1);
|
||||||
console.log(b + 1);
|
console.log(b + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
function f2() {
|
function f2() {
|
||||||
var a = 1, b = 2, c = 3;
|
var a = 1, b = 2, c = 3;
|
||||||
b = c;
|
b = c;
|
||||||
@@ -92,7 +90,6 @@ modified: {
|
|||||||
console.log(a + c);
|
console.log(a + c);
|
||||||
console.log(a + b + c);
|
console.log(a + b + c);
|
||||||
}
|
}
|
||||||
|
|
||||||
function f3() {
|
function f3() {
|
||||||
var a = 1, b = 2, c = 3;
|
var a = 1, b = 2, c = 3;
|
||||||
b *= c;
|
b *= c;
|
||||||
@@ -101,7 +98,6 @@ modified: {
|
|||||||
console.log(a + c);
|
console.log(a + c);
|
||||||
console.log(a + b + c);
|
console.log(a + b + c);
|
||||||
}
|
}
|
||||||
|
|
||||||
function f4() {
|
function f4() {
|
||||||
var a = 1, b = 2, c = 3;
|
var a = 1, b = 2, c = 3;
|
||||||
if (a) {
|
if (a) {
|
||||||
@@ -114,28 +110,26 @@ modified: {
|
|||||||
console.log(a + c);
|
console.log(a + c);
|
||||||
console.log(a + b + c);
|
console.log(a + b + c);
|
||||||
}
|
}
|
||||||
|
|
||||||
function f5(a) {
|
function f5(a) {
|
||||||
B = a;
|
B = a;
|
||||||
console.log(A ? 'yes' : 'no');
|
console.log(typeof A ? "yes" : "no");
|
||||||
console.log(B ? 'yes' : 'no');
|
console.log(typeof B ? "yes" : "no");
|
||||||
}
|
}
|
||||||
|
f0(), f1(), f2(), f3(), f4(), f5();
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f0() {
|
function f0() {
|
||||||
var b = 2;
|
var b = 2;
|
||||||
b++;
|
b++;
|
||||||
console.log(2);
|
console.log(2);
|
||||||
console.log(b + 1);
|
console.log(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
function f1() {
|
function f1() {
|
||||||
var b = 2;
|
var b = 2;
|
||||||
--b;
|
--b;
|
||||||
console.log(2);
|
console.log(2);
|
||||||
console.log(b + 1);
|
console.log(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
function f2() {
|
function f2() {
|
||||||
3;
|
3;
|
||||||
console.log(4);
|
console.log(4);
|
||||||
@@ -143,16 +137,14 @@ modified: {
|
|||||||
console.log(4);
|
console.log(4);
|
||||||
console.log(7);
|
console.log(7);
|
||||||
}
|
}
|
||||||
|
|
||||||
function f3() {
|
function f3() {
|
||||||
var b = 2;
|
var b = 2;
|
||||||
b *= 3;
|
b *= 3;
|
||||||
console.log(1 + b);
|
console.log(7);
|
||||||
console.log(b + 3);
|
console.log(9);
|
||||||
console.log(4);
|
console.log(4);
|
||||||
console.log(1 + b + 3);
|
console.log(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
function f4() {
|
function f4() {
|
||||||
var b = 2, c = 3;
|
var b = 2, c = 3;
|
||||||
b = c;
|
b = c;
|
||||||
@@ -161,13 +153,33 @@ modified: {
|
|||||||
console.log(1 + c);
|
console.log(1 + c);
|
||||||
console.log(1 + b + c);
|
console.log(1 + b + c);
|
||||||
}
|
}
|
||||||
|
|
||||||
function f5(a) {
|
function f5(a) {
|
||||||
B = a;
|
B = a;
|
||||||
console.log(A ? 'yes' : 'no');
|
console.log(typeof A ? "yes" : "no");
|
||||||
console.log(B ? 'yes' : 'no');
|
console.log(typeof B ? "yes" : "no");
|
||||||
}
|
}
|
||||||
|
f0(), f1(), f2(), f3(), f4(), f5();
|
||||||
}
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"2",
|
||||||
|
"4",
|
||||||
|
"2",
|
||||||
|
"2",
|
||||||
|
"4",
|
||||||
|
"6",
|
||||||
|
"4",
|
||||||
|
"7",
|
||||||
|
"7",
|
||||||
|
"9",
|
||||||
|
"4",
|
||||||
|
"10",
|
||||||
|
"4",
|
||||||
|
"6",
|
||||||
|
"4",
|
||||||
|
"7",
|
||||||
|
"yes",
|
||||||
|
"yes",
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe_evaluate: {
|
unsafe_evaluate: {
|
||||||
@@ -299,7 +311,7 @@ unsafe_evaluate_modified: {
|
|||||||
console.log(function(){ var o={p:1}; o.p++; console.log(o.p); return o.p; }());
|
console.log(function(){ var o={p:1}; o.p++; console.log(o.p); return o.p; }());
|
||||||
console.log(function(){ var o={p:2}; --o.p; console.log(o.p); return o.p; }());
|
console.log(function(){ var o={p:2}; --o.p; console.log(o.p); return o.p; }());
|
||||||
console.log(function(){ var o={p:3}; o.p += ""; console.log(o.p); return o.p; }());
|
console.log(function(){ var o={p:3}; o.p += ""; console.log(o.p); return o.p; }());
|
||||||
console.log(function(){ var o={p:4}; o = {}; console.log(o.p); return o.p; }());
|
console.log(function(){ var o; o = {}; console.log(o.p); return o.p; }());
|
||||||
console.log(function(){ var o={p:5}; o.p = -9; console.log(o.p); return o.p; }());
|
console.log(function(){ var o={p:5}; o.p = -9; console.log(o.p); return o.p; }());
|
||||||
function inc() { this.p++; }
|
function inc() { this.p++; }
|
||||||
console.log(function(){ var o={p:6}; inc.call(o); console.log(o.p); return o.p; }());
|
console.log(function(){ var o={p:6}; inc.call(o); console.log(o.p); return o.p; }());
|
||||||
@@ -745,7 +757,7 @@ iife: {
|
|||||||
expect: {
|
expect: {
|
||||||
!function(a, b, c) {
|
!function(a, b, c) {
|
||||||
b++;
|
b++;
|
||||||
console.log(0, 1 * b, 5);
|
console.log(0, 3, 5);
|
||||||
}(1, 2, 3);
|
}(1, 2, 3);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
@@ -766,7 +778,7 @@ iife_new: {
|
|||||||
expect: {
|
expect: {
|
||||||
var A = new function(a, b, c) {
|
var A = new function(a, b, c) {
|
||||||
b++;
|
b++;
|
||||||
console.log(0, 1 * b, 5);
|
console.log(0, 3, 5);
|
||||||
}(1, 2, 3);
|
}(1, 2, 3);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
@@ -1355,10 +1367,9 @@ defun_inline_1: {
|
|||||||
function f() {
|
function f() {
|
||||||
return function(b) {
|
return function(b) {
|
||||||
return b;
|
return b;
|
||||||
}(2) + h();
|
}(2) + function h() {
|
||||||
function h() {
|
|
||||||
return h();
|
return h();
|
||||||
}
|
}();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1382,12 +1393,11 @@ defun_inline_2: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f() {
|
function f() {
|
||||||
function h() {
|
|
||||||
return h();
|
|
||||||
}
|
|
||||||
return function(b) {
|
return function(b) {
|
||||||
return b;
|
return b;
|
||||||
}(2) + h();
|
}(2) + function h() {
|
||||||
|
return h();
|
||||||
|
}();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2314,8 +2324,7 @@ delay_def: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f() {
|
function f() {
|
||||||
return a;
|
return;
|
||||||
var a;
|
|
||||||
}
|
}
|
||||||
function g() {
|
function g() {
|
||||||
return a;
|
return a;
|
||||||
@@ -2326,6 +2335,28 @@ delay_def: {
|
|||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delay_def_lhs: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
long_name++;
|
||||||
|
return long_name;
|
||||||
|
var long_name;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
long_name++;
|
||||||
|
return long_name;
|
||||||
|
var long_name;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "NaN"
|
||||||
|
}
|
||||||
|
|
||||||
booleans: {
|
booleans: {
|
||||||
options = {
|
options = {
|
||||||
booleans: true,
|
booleans: true,
|
||||||
@@ -4954,3 +4985,551 @@ issue_2598: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "true"
|
expect_stdout: "true"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var_if: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
if (x()) {
|
||||||
|
var a;
|
||||||
|
if (!g) a = true;
|
||||||
|
if (a) g();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
if (x()) {
|
||||||
|
var a;
|
||||||
|
if (!g) a = true;
|
||||||
|
if (a) g();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_assign: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(typeof a);
|
||||||
|
a = 42;
|
||||||
|
console.log(typeof a);
|
||||||
|
function a() {}
|
||||||
|
console.log(typeof a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(typeof a);
|
||||||
|
a = 42;
|
||||||
|
console.log(typeof a);
|
||||||
|
function a() {}
|
||||||
|
console.log(typeof a);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"function",
|
||||||
|
"number",
|
||||||
|
"number",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_var_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
typeofs: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 42, b;
|
||||||
|
function a() {}
|
||||||
|
function b() {}
|
||||||
|
console.log(typeof a, typeof b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 42;
|
||||||
|
function a() {}
|
||||||
|
console.log(typeof a, "function");
|
||||||
|
}
|
||||||
|
expect_stdout: "number function"
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_var_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
typeofs: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function a() {}
|
||||||
|
function b() {}
|
||||||
|
var a = 42, b;
|
||||||
|
console.log(typeof a, typeof b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function a() {}
|
||||||
|
var a = 42;
|
||||||
|
console.log(typeof a, "function");
|
||||||
|
}
|
||||||
|
expect_stdout: "number function"
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_var_3: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
typeofs: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function a() {}
|
||||||
|
function b() {}
|
||||||
|
console.log(typeof a, typeof b);
|
||||||
|
var a = 42, b;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function a() {}
|
||||||
|
console.log(typeof a, "function");
|
||||||
|
var a = 42;
|
||||||
|
}
|
||||||
|
expect_stdout: "function function"
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_catch_1: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function a() {}
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (a) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (a) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_catch_2: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
function a() {}
|
||||||
|
throw 42;
|
||||||
|
} catch (a) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (a) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_catch_3: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
function a() {}
|
||||||
|
} catch (a) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (a) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_catch_4: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (a) {
|
||||||
|
function a() {}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (a) {
|
||||||
|
function a() {}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_catch_5: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (a) {
|
||||||
|
console.log(a);
|
||||||
|
function a() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (a) {
|
||||||
|
console.log(a);
|
||||||
|
function a() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_catch_6: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (a) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
function a() {}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (a) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
duplicate_lambda_defun_name_1: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function f(a) {
|
||||||
|
function f() {}
|
||||||
|
return f.length;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function f(a) {
|
||||||
|
function f() {}
|
||||||
|
return f.length;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
duplicate_lambda_defun_name_2: {
|
||||||
|
options = {
|
||||||
|
passes: 2,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function f(a) {
|
||||||
|
function f() {}
|
||||||
|
return f.length;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a) {
|
||||||
|
return function() {}.length;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2774: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log({
|
||||||
|
get a() {
|
||||||
|
var b;
|
||||||
|
(b = true) && b.c;
|
||||||
|
b = void 0;
|
||||||
|
}
|
||||||
|
}.a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log({
|
||||||
|
get a() {
|
||||||
|
var b;
|
||||||
|
(b = true) && b.c;
|
||||||
|
b = void 0;
|
||||||
|
}
|
||||||
|
}.a);
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2799_1: {
|
||||||
|
options = {
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
return f;
|
||||||
|
function f(n) {
|
||||||
|
function g(i) {
|
||||||
|
return i && i + g(i - 1);
|
||||||
|
}
|
||||||
|
function h(j) {
|
||||||
|
return g(j);
|
||||||
|
}
|
||||||
|
return h(n);
|
||||||
|
}
|
||||||
|
}()(5));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
return function(n) {
|
||||||
|
return function(j) {
|
||||||
|
return function g(i) {
|
||||||
|
return i && i + g(i - 1);
|
||||||
|
}(j);
|
||||||
|
}(n);
|
||||||
|
}
|
||||||
|
}()(5));
|
||||||
|
}
|
||||||
|
expect_stdout: "15"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2799_2: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
unsafe_proto: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
function foo() {
|
||||||
|
Function.prototype.call.apply(console.log, [ null, "PASS" ]);
|
||||||
|
}
|
||||||
|
foo();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
(function() {
|
||||||
|
(function() {}).call.apply(console.log, [ null, "PASS" ]);
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2836: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
return "FAIL";
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
function f() {
|
||||||
|
return "PASS";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
return "PASS";
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
lvalues_def_1: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var b = 1;
|
||||||
|
var a = b++, b = NaN;
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var b = 1;
|
||||||
|
var a = b++;
|
||||||
|
b = NaN;
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect_stdout: "1 NaN"
|
||||||
|
}
|
||||||
|
|
||||||
|
lvalues_def_2: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var b = 1;
|
||||||
|
var a = b += 1, b = NaN;
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var b = 1;
|
||||||
|
var a = b += 1;
|
||||||
|
b = NaN;
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect_stdout: "2 NaN"
|
||||||
|
}
|
||||||
|
|
||||||
|
chained_assignments: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unsafe: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
var a = [0x5e, 0xad, 0xbe, 0xef];
|
||||||
|
var b = 0;
|
||||||
|
b |= a[0];
|
||||||
|
b <<= 8;
|
||||||
|
b |= a[1];
|
||||||
|
b <<= 8;
|
||||||
|
b |= a[2];
|
||||||
|
b <<= 8;
|
||||||
|
b |= a[3];
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
console.log(f().toString(16));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("5eadbeef");
|
||||||
|
}
|
||||||
|
expect_stdout: "5eadbeef"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2860_1: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a) {
|
||||||
|
return a ^= 1;
|
||||||
|
a ^= 2;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a) {
|
||||||
|
return 1 ^ a;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2860_2: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 2,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a) {
|
||||||
|
return a ^= 1;
|
||||||
|
a ^= 2;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(1);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2869: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var c = "FAIL";
|
||||||
|
(function f(a) {
|
||||||
|
var a;
|
||||||
|
if (!f) a = 0;
|
||||||
|
if (a) c = "PASS";
|
||||||
|
})(1);
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c = "FAIL";
|
||||||
|
(function f(a) {
|
||||||
|
var a;
|
||||||
|
if (!f) a = 0;
|
||||||
|
if (a) c = "PASS";
|
||||||
|
})(1);
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -288,7 +288,7 @@ unsafe_undefined: {
|
|||||||
if_return: true,
|
if_return: true,
|
||||||
sequences: true,
|
sequences: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
unsafe: true,
|
unsafe_undefined: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f(undefined) {
|
function f(undefined) {
|
||||||
@@ -796,3 +796,84 @@ cascade_assignment_in_return: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hoist_defun: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
x();
|
||||||
|
function f() {}
|
||||||
|
y();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {}
|
||||||
|
x(), y();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hoist_decl: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
w();
|
||||||
|
var b = x();
|
||||||
|
y();
|
||||||
|
for (var c; 0;) z();
|
||||||
|
var d;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
w();
|
||||||
|
var b = x(), c, d;
|
||||||
|
for (y(); 0;) z();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for_init_var: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
unused: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS";
|
||||||
|
(function() {
|
||||||
|
var b = 42;
|
||||||
|
for (var c = 5; c > 0;) c--;
|
||||||
|
a = "FAIL";
|
||||||
|
var a;
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "PASS";
|
||||||
|
(function() {
|
||||||
|
for (var b = 42, c = 5, a; c > 0;) c--;
|
||||||
|
a = "FAIL";
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
forin: {
|
||||||
|
options = {
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = [];
|
||||||
|
o.push("PASS");
|
||||||
|
for (var a in o)
|
||||||
|
console.log(o[a]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = [];
|
||||||
|
for (var a in o.push("PASS"), o)
|
||||||
|
console.log(o[a]);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ typeof_defun_1: {
|
|||||||
g = 42;
|
g = 42;
|
||||||
console.log("YES");
|
console.log("YES");
|
||||||
"function" == typeof g && g();
|
"function" == typeof g && g();
|
||||||
h();
|
"function" == typeof h && h();
|
||||||
}
|
}
|
||||||
expect_stdout: [
|
expect_stdout: [
|
||||||
"YES",
|
"YES",
|
||||||
@@ -138,3 +138,166 @@ typeof_defun_2: {
|
|||||||
"2",
|
"2",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
duplicate_defun_arg_name: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
typeofs: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function long_name(long_name) {
|
||||||
|
return typeof long_name;
|
||||||
|
}
|
||||||
|
console.log(typeof long_name, long_name());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function long_name(long_name) {
|
||||||
|
return typeof long_name;
|
||||||
|
}
|
||||||
|
console.log(typeof long_name, long_name());
|
||||||
|
}
|
||||||
|
expect_stdout: "function undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
duplicate_lambda_arg_name: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
typeofs: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function long_name(long_name) {
|
||||||
|
return typeof long_name;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function long_name(long_name) {
|
||||||
|
return typeof long_name;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2728_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
typeofs: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function arguments() {
|
||||||
|
console.log(typeof arguments);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function arguments() {
|
||||||
|
console.log(typeof arguments);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "object"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2728_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
typeofs: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function arguments() {
|
||||||
|
return typeof arguments;
|
||||||
|
}
|
||||||
|
console.log(typeof arguments, arguments());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function arguments() {
|
||||||
|
return typeof arguments;
|
||||||
|
}
|
||||||
|
console.log(typeof arguments, arguments());
|
||||||
|
}
|
||||||
|
expect_stdout: "function object"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2728_3: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
typeofs: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
function arguments() {
|
||||||
|
}
|
||||||
|
console.log(typeof arguments);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
function arguments() {
|
||||||
|
}
|
||||||
|
console.log("function");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2728_4: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
typeofs: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function arguments() {
|
||||||
|
}
|
||||||
|
console.log(typeof arguments);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function arguments() {
|
||||||
|
}
|
||||||
|
console.log("function");
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2728_5: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
typeofs: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function arguments(arguments) {
|
||||||
|
console.log(typeof arguments);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function arguments(arguments) {
|
||||||
|
console.log(typeof arguments);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2728_6: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
typeofs: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function arguments(arguments) {
|
||||||
|
return typeof arguments;
|
||||||
|
}
|
||||||
|
console.log(typeof arguments, arguments());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function arguments(arguments) {
|
||||||
|
return typeof arguments;
|
||||||
|
}
|
||||||
|
console.log(typeof arguments, arguments());
|
||||||
|
}
|
||||||
|
expect_stdout: "function undefined"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
var a = bar(1+2);
|
var x = bar(1+2);
|
||||||
var b = baz(3+9);
|
var y = baz(3+9);
|
||||||
print('q' + 'u' + 'x', a, b);
|
print('q' + 'u' + 'x', x, y);
|
||||||
foo(5+6);
|
foo(5+6);
|
||||||
|
|||||||
6
test/input/rename/input.js
Normal file
6
test/input/rename/input.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
function f(x) {
|
||||||
|
return g(x);
|
||||||
|
function g(x) {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,11 +5,7 @@
|
|||||||
|
|
||||||
var site = "http://browserbench.org/JetStream";
|
var site = "http://browserbench.org/JetStream";
|
||||||
if (typeof phantom == "undefined") {
|
if (typeof phantom == "undefined") {
|
||||||
// workaround for tty output truncation upon process.exit()
|
require("../tools/exit");
|
||||||
[process.stdout, process.stderr].forEach(function(stream){
|
|
||||||
if (stream._handle && stream._handle.setBlocking)
|
|
||||||
stream._handle.setBlocking(true);
|
|
||||||
});
|
|
||||||
var args = process.argv.slice(2);
|
var args = process.argv.slice(2);
|
||||||
var debug = args.indexOf("--debug");
|
var debug = args.indexOf("--debug");
|
||||||
if (debug >= 0) {
|
if (debug >= 0) {
|
||||||
|
|||||||
@@ -1,29 +1,24 @@
|
|||||||
var Mocha = require('mocha'),
|
var fs = require("fs");
|
||||||
fs = require('fs'),
|
var Mocha = require("mocha");
|
||||||
path = require('path');
|
var path = require("path");
|
||||||
|
|
||||||
// Instantiate a Mocha instance.
|
// Instantiate a Mocha instance
|
||||||
var mocha = new Mocha({});
|
var mocha = new Mocha({
|
||||||
|
timeout: 5000
|
||||||
|
});
|
||||||
|
var testDir = __dirname + "/mocha/";
|
||||||
|
|
||||||
var testDir = __dirname + '/mocha/';
|
// Add each .js file to the Mocha instance
|
||||||
|
fs.readdirSync(testDir).filter(function(file) {
|
||||||
// Add each .js file to the mocha instance
|
return /\.js$/.test(file);
|
||||||
fs.readdirSync(testDir).filter(function(file){
|
}).forEach(function(file) {
|
||||||
// Only keep the .js files
|
mocha.addFile(path.join(testDir, file));
|
||||||
return file.substr(-3) === '.js';
|
|
||||||
|
|
||||||
}).forEach(function(file){
|
|
||||||
mocha.addFile(
|
|
||||||
path.join(testDir, file)
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = function() {
|
module.exports = function() {
|
||||||
mocha.run(function(failures) {
|
mocha.run(function(failures) {
|
||||||
if (failures !== 0) {
|
if (failures) process.on("exit", function() {
|
||||||
process.on('exit', function () {
|
process.exit(failures);
|
||||||
process.exit(failures);
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -650,4 +650,36 @@ describe("bin/uglifyjs", function () {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
it("Should work with explicit --rename", function(done) {
|
||||||
|
var command = uglifyjscmd + " test/input/rename/input.js --rename";
|
||||||
|
exec(command, function(err, stdout, stderr) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(stdout, "function f(a){return b(a);function b(c){return c}}\n");
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should work with explicit --no-rename", function(done) {
|
||||||
|
var command = uglifyjscmd + " test/input/rename/input.js -mc --no-rename";
|
||||||
|
exec(command, function(err, stdout, stderr) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(stdout, "function f(n){return function(n){return n}(n)}\n");
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should work with implicit --rename", function(done) {
|
||||||
|
var command = uglifyjscmd + " test/input/rename/input.js -mc";
|
||||||
|
exec(command, function(err, stdout, stderr) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(stdout, "function f(n){return n}\n");
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should work with implicit --no-rename", function(done) {
|
||||||
|
var command = uglifyjscmd + " test/input/rename/input.js -c";
|
||||||
|
exec(command, function(err, stdout, stderr) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(stdout, "function f(x){return function(x){return x}(x)}\n");
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -219,4 +219,24 @@ describe("Comment", function() {
|
|||||||
if (result.error) throw result.error;
|
if (result.error) throw result.error;
|
||||||
assert.strictEqual(result.code, "/*a*/ /*b*/(function(){/*c*/}/*d*/ /*e*/)();");
|
assert.strictEqual(result.code, "/*a*/ /*b*/(function(){/*c*/}/*d*/ /*e*/)();");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Should output line comments after statements", function() {
|
||||||
|
var result = uglify.minify([
|
||||||
|
"x()//foo",
|
||||||
|
"{y()//bar",
|
||||||
|
"}",
|
||||||
|
].join("\n"), {
|
||||||
|
compress: false,
|
||||||
|
mangle: false,
|
||||||
|
output: {
|
||||||
|
comments: "all",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
assert.strictEqual(result.code, [
|
||||||
|
"x();//foo",
|
||||||
|
"{y();//bar",
|
||||||
|
"}",
|
||||||
|
].join("\n"));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -42,8 +42,15 @@ describe("minify", function() {
|
|||||||
original += code;
|
original += code;
|
||||||
compressed += result.code;
|
compressed += result.code;
|
||||||
});
|
});
|
||||||
assert.strictEqual(JSON.stringify(cache).slice(0, 20), '{"cname":5,"props":{');
|
assert.strictEqual(JSON.stringify(cache).slice(0, 10), '{"props":{');
|
||||||
assert.strictEqual(compressed, 'function n(n){return 3*n}function r(n){return n/2}var c=console.log.bind(console);function l(o){c("Foo:",2*o)}var f=n(3),i=r(12);c("qux",f,i),l(11);');
|
assert.strictEqual(compressed, [
|
||||||
|
"function n(n){return 3*n}",
|
||||||
|
"function r(n){return n/2}",
|
||||||
|
"var o=console.log.bind(console);",
|
||||||
|
'function c(n){o("Foo:",2*n)}',
|
||||||
|
"var a=n(3),b=r(12);",
|
||||||
|
'o("qux",a,b),c(11);',
|
||||||
|
].join(""));
|
||||||
assert.strictEqual(run_code(compressed), run_code(original));
|
assert.strictEqual(run_code(compressed), run_code(original));
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -68,12 +75,48 @@ describe("minify", function() {
|
|||||||
original += code;
|
original += code;
|
||||||
compressed += result.code;
|
compressed += result.code;
|
||||||
});
|
});
|
||||||
assert.strictEqual(JSON.stringify(cache).slice(0, 28), '{"vars":{"cname":5,"props":{');
|
assert.strictEqual(JSON.stringify(cache).slice(0, 18), '{"vars":{"props":{');
|
||||||
assert.strictEqual(compressed, 'function n(n){return 3*n}function r(n){return n/2}var c=console.log.bind(console);function l(o){c("Foo:",2*o)}var f=n(3),i=r(12);c("qux",f,i),l(11);');
|
assert.strictEqual(compressed, [
|
||||||
|
"function n(n){return 3*n}",
|
||||||
|
"function r(n){return n/2}",
|
||||||
|
"var o=console.log.bind(console);",
|
||||||
|
'function c(n){o("Foo:",2*n)}',
|
||||||
|
"var a=n(3),b=r(12);",
|
||||||
|
'o("qux",a,b),c(11);',
|
||||||
|
].join(""));
|
||||||
assert.strictEqual(run_code(compressed), run_code(original));
|
assert.strictEqual(run_code(compressed), run_code(original));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not parse invalid use of reserved words", function() {
|
it("Should avoid mangled names in cache", function() {
|
||||||
|
var cache = {};
|
||||||
|
var original = "";
|
||||||
|
var compressed = "";
|
||||||
|
[
|
||||||
|
'"xxxyy";var i={s:1};',
|
||||||
|
'"xxyyy";var j={t:2,u:3},k=4;',
|
||||||
|
'console.log(i.s,j.t,j.u,k);',
|
||||||
|
].forEach(function(code) {
|
||||||
|
var result = Uglify.minify(code, {
|
||||||
|
compress: false,
|
||||||
|
mangle: {
|
||||||
|
properties: true,
|
||||||
|
toplevel: true
|
||||||
|
},
|
||||||
|
nameCache: cache
|
||||||
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
original += code;
|
||||||
|
compressed += result.code;
|
||||||
|
});
|
||||||
|
assert.strictEqual(compressed, [
|
||||||
|
'"xxxyy";var x={x:1};',
|
||||||
|
'"xxyyy";var y={y:2,a:3},a=4;',
|
||||||
|
'console.log(x.x,y.y,y.a,a);',
|
||||||
|
].join(""));
|
||||||
|
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 enum(){}").error, undefined);
|
||||||
assert.strictEqual(Uglify.minify("function static(){}").error, undefined);
|
assert.strictEqual(Uglify.minify("function static(){}").error, undefined);
|
||||||
assert.strictEqual(Uglify.minify("function this(){}").error.message, "Unexpected token: name (this)");
|
assert.strictEqual(Uglify.minify("function this(){}").error.message, "Unexpected token: name (this)");
|
||||||
@@ -330,4 +373,18 @@ describe("minify", function() {
|
|||||||
assert.strictEqual(stat.print_to_string(), "a=x()");
|
assert.strictEqual(stat.print_to_string(), "a=x()");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("rename", function() {
|
||||||
|
it("Should be repeatable", function() {
|
||||||
|
var code = "!function(x){return x(x)}(y);";
|
||||||
|
for (var i = 0; i < 2; i++) {
|
||||||
|
assert.strictEqual(Uglify.minify(code, {
|
||||||
|
compress: {
|
||||||
|
toplevel: true,
|
||||||
|
},
|
||||||
|
rename: true,
|
||||||
|
}).code, "var a;(a=y)(a);");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ var semver = require("semver");
|
|||||||
var tests_dir = path.dirname(module.filename);
|
var tests_dir = path.dirname(module.filename);
|
||||||
var failures = 0;
|
var failures = 0;
|
||||||
var failed_files = {};
|
var failed_files = {};
|
||||||
|
var minify_options = require("./ufuzz.json").map(JSON.stringify);
|
||||||
|
|
||||||
run_compress_tests();
|
run_compress_tests();
|
||||||
if (failures) {
|
if (failures) {
|
||||||
@@ -100,6 +101,15 @@ function run_compress_tests() {
|
|||||||
quote_style: 3,
|
quote_style: 3,
|
||||||
keep_quoted_props: true
|
keep_quoted_props: true
|
||||||
});
|
});
|
||||||
|
try {
|
||||||
|
U.parse(input_code);
|
||||||
|
} catch (ex) {
|
||||||
|
log("!!! Cannot parse input\n---INPUT---\n{input}\n--PARSE ERROR--\n{error}\n\n", {
|
||||||
|
input: input_formatted,
|
||||||
|
error: ex,
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
var options = U.defaults(test.options, {
|
var options = U.defaults(test.options, {
|
||||||
warnings: false
|
warnings: false
|
||||||
});
|
});
|
||||||
@@ -139,78 +149,77 @@ function run_compress_tests() {
|
|||||||
output: output,
|
output: output,
|
||||||
expected: expect
|
expected: expect
|
||||||
});
|
});
|
||||||
failures++;
|
return false;
|
||||||
failed_files[file] = 1;
|
|
||||||
}
|
}
|
||||||
else {
|
// expect == output
|
||||||
// expect == output
|
try {
|
||||||
try {
|
U.parse(output);
|
||||||
var reparsed_ast = U.parse(output);
|
} catch (ex) {
|
||||||
} catch (ex) {
|
log("!!! Test matched expected result but cannot parse output\n---INPUT---\n{input}\n---OUTPUT---\n{output}\n--REPARSE ERROR--\n{error}\n\n", {
|
||||||
log("!!! Test matched expected result but cannot parse output\n---INPUT---\n{input}\n---OUTPUT---\n{output}\n--REPARSE ERROR--\n{error}\n\n", {
|
input: input_formatted,
|
||||||
|
output: output,
|
||||||
|
error: ex,
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (test.expect_warnings) {
|
||||||
|
U.AST_Node.warn_function = original_warn_function;
|
||||||
|
var expected_warnings = make_code(test.expect_warnings, {
|
||||||
|
beautify: false,
|
||||||
|
quote_style: 2, // force double quote to match JSON
|
||||||
|
});
|
||||||
|
warnings_emitted = warnings_emitted.map(function(input) {
|
||||||
|
return input.split(process.cwd() + path.sep).join("").split(path.sep).join("/");
|
||||||
|
});
|
||||||
|
var actual_warnings = JSON.stringify(warnings_emitted);
|
||||||
|
if (expected_warnings != actual_warnings) {
|
||||||
|
log("!!! failed\n---INPUT---\n{input}\n---EXPECTED WARNINGS---\n{expected_warnings}\n---ACTUAL WARNINGS---\n{actual_warnings}\n\n", {
|
||||||
input: input_formatted,
|
input: input_formatted,
|
||||||
output: output,
|
expected_warnings: expected_warnings,
|
||||||
error: ex.toString(),
|
actual_warnings: actual_warnings,
|
||||||
});
|
});
|
||||||
failures++;
|
return false;
|
||||||
failed_files[file] = 1;
|
|
||||||
}
|
|
||||||
if (test.expect_warnings) {
|
|
||||||
U.AST_Node.warn_function = original_warn_function;
|
|
||||||
var expected_warnings = make_code(test.expect_warnings, {
|
|
||||||
beautify: false,
|
|
||||||
quote_style: 2, // force double quote to match JSON
|
|
||||||
});
|
|
||||||
warnings_emitted = warnings_emitted.map(function(input) {
|
|
||||||
return input.split(process.cwd() + path.sep).join("").split(path.sep).join("/");
|
|
||||||
});
|
|
||||||
var actual_warnings = JSON.stringify(warnings_emitted);
|
|
||||||
if (expected_warnings != actual_warnings) {
|
|
||||||
log("!!! failed\n---INPUT---\n{input}\n---EXPECTED WARNINGS---\n{expected_warnings}\n---ACTUAL WARNINGS---\n{actual_warnings}\n\n", {
|
|
||||||
input: input_formatted,
|
|
||||||
expected_warnings: expected_warnings,
|
|
||||||
actual_warnings: actual_warnings,
|
|
||||||
});
|
|
||||||
failures++;
|
|
||||||
failed_files[file] = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (test.expect_stdout
|
|
||||||
&& (!test.node_version || semver.satisfies(process.version, test.node_version))) {
|
|
||||||
var stdout = sandbox.run_code(input_code);
|
|
||||||
if (test.expect_stdout === true) {
|
|
||||||
test.expect_stdout = stdout;
|
|
||||||
}
|
|
||||||
if (!sandbox.same_stdout(test.expect_stdout, stdout)) {
|
|
||||||
log("!!! Invalid input or expected stdout\n---INPUT---\n{input}\n---EXPECTED {expected_type}---\n{expected}\n---ACTUAL {actual_type}---\n{actual}\n\n", {
|
|
||||||
input: input_formatted,
|
|
||||||
expected_type: typeof test.expect_stdout == "string" ? "STDOUT" : "ERROR",
|
|
||||||
expected: test.expect_stdout,
|
|
||||||
actual_type: typeof stdout == "string" ? "STDOUT" : "ERROR",
|
|
||||||
actual: stdout,
|
|
||||||
});
|
|
||||||
failures++;
|
|
||||||
failed_files[file] = 1;
|
|
||||||
} else {
|
|
||||||
stdout = sandbox.run_code(output);
|
|
||||||
if (!sandbox.same_stdout(test.expect_stdout, stdout)) {
|
|
||||||
log("!!! failed\n---INPUT---\n{input}\n---EXPECTED {expected_type}---\n{expected}\n---ACTUAL {actual_type}---\n{actual}\n\n", {
|
|
||||||
input: input_formatted,
|
|
||||||
expected_type: typeof test.expect_stdout == "string" ? "STDOUT" : "ERROR",
|
|
||||||
expected: test.expect_stdout,
|
|
||||||
actual_type: typeof stdout == "string" ? "STDOUT" : "ERROR",
|
|
||||||
actual: stdout,
|
|
||||||
});
|
|
||||||
failures++;
|
|
||||||
failed_files[file] = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (test.expect_stdout
|
||||||
|
&& (!test.node_version || semver.satisfies(process.version, test.node_version))) {
|
||||||
|
var stdout = sandbox.run_code(input_code);
|
||||||
|
if (test.expect_stdout === true) {
|
||||||
|
test.expect_stdout = stdout;
|
||||||
|
}
|
||||||
|
if (!sandbox.same_stdout(test.expect_stdout, stdout)) {
|
||||||
|
log("!!! Invalid input or expected stdout\n---INPUT---\n{input}\n---EXPECTED {expected_type}---\n{expected}\n---ACTUAL {actual_type}---\n{actual}\n\n", {
|
||||||
|
input: input_formatted,
|
||||||
|
expected_type: typeof test.expect_stdout == "string" ? "STDOUT" : "ERROR",
|
||||||
|
expected: test.expect_stdout,
|
||||||
|
actual_type: typeof stdout == "string" ? "STDOUT" : "ERROR",
|
||||||
|
actual: stdout,
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
stdout = sandbox.run_code(output);
|
||||||
|
if (!sandbox.same_stdout(test.expect_stdout, stdout)) {
|
||||||
|
log("!!! failed\n---INPUT---\n{input}\n---EXPECTED {expected_type}---\n{expected}\n---ACTUAL {actual_type}---\n{actual}\n\n", {
|
||||||
|
input: input_formatted,
|
||||||
|
expected_type: typeof test.expect_stdout == "string" ? "STDOUT" : "ERROR",
|
||||||
|
expected: test.expect_stdout,
|
||||||
|
actual_type: typeof stdout == "string" ? "STDOUT" : "ERROR",
|
||||||
|
actual: stdout,
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!reminify(test.options, input_code, input_formatted, test.expect_stdout)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
var tests = parse_test(path.resolve(dir, file));
|
var tests = parse_test(path.resolve(dir, file));
|
||||||
for (var i in tests) if (tests.hasOwnProperty(i)) {
|
for (var i in tests) if (tests.hasOwnProperty(i)) {
|
||||||
test_case(tests[i]);
|
if (!test_case(tests[i])) {
|
||||||
|
failures++;
|
||||||
|
failed_files[file] = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
files.forEach(function(file){
|
files.forEach(function(file){
|
||||||
@@ -346,3 +355,46 @@ function evaluate(code) {
|
|||||||
code = make_code(code, { beautify: true });
|
code = make_code(code, { beautify: true });
|
||||||
return new Function("return(" + code + ")")();
|
return new Function("return(" + code + ")")();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try to reminify original input with standard options
|
||||||
|
// to see if it matches expect_stdout.
|
||||||
|
function reminify(orig_options, input_code, input_formatted, expect_stdout) {
|
||||||
|
for (var i = 0; i < minify_options.length; i++) {
|
||||||
|
var options = JSON.parse(minify_options[i]);
|
||||||
|
if (options.compress) [
|
||||||
|
"keep_fargs",
|
||||||
|
"keep_fnames",
|
||||||
|
].forEach(function(name) {
|
||||||
|
if (name in orig_options) {
|
||||||
|
options.compress[name] = orig_options[name];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var options_formatted = JSON.stringify(options, null, 4);
|
||||||
|
var result = U.minify(input_code, options);
|
||||||
|
if (result.error) {
|
||||||
|
log("!!! failed input reminify\n---INPUT---\n{input}\n--ERROR---\n{error}\n\n", {
|
||||||
|
input: input_formatted,
|
||||||
|
error: result.error,
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
var stdout = sandbox.run_code(result.code);
|
||||||
|
if (typeof expect_stdout != "string" && typeof stdout != "string" && expect_stdout.name == stdout.name) {
|
||||||
|
stdout = expect_stdout;
|
||||||
|
}
|
||||||
|
if (!sandbox.same_stdout(expect_stdout, stdout)) {
|
||||||
|
log("!!! failed running reminified input\n---INPUT---\n{input}\n---OPTIONS---\n{options}\n---OUTPUT---\n{output}\n---EXPECTED {expected_type}---\n{expected}\n---ACTUAL {actual_type}---\n{actual}\n\n", {
|
||||||
|
input: input_formatted,
|
||||||
|
options: options_formatted,
|
||||||
|
output: result.code,
|
||||||
|
expected_type: typeof expect_stdout == "string" ? "STDOUT" : "ERROR",
|
||||||
|
expected: expect_stdout,
|
||||||
|
actual_type: typeof stdout == "string" ? "STDOUT" : "ERROR",
|
||||||
|
actual: stdout,
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,24 +17,30 @@ function safe_log(arg, level) {
|
|||||||
return arg;
|
return arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function strip_func_ids(text) {
|
||||||
|
return text.toString().replace(/F[0-9]{6}N/g, "<F<>N>");
|
||||||
|
}
|
||||||
|
|
||||||
var FUNC_TOSTRING = [
|
var FUNC_TOSTRING = [
|
||||||
|
"[ Array, Boolean, Error, Function, Number, Object, RegExp, String].forEach(function(f) {",
|
||||||
|
" f.toString = Function.prototype.toString;",
|
||||||
|
" f.valueOf = Function.prototype.valueOf;",
|
||||||
|
"});",
|
||||||
"Function.prototype.toString = Function.prototype.valueOf = function() {",
|
"Function.prototype.toString = Function.prototype.valueOf = function() {",
|
||||||
" var id = 100000;",
|
" var id = 100000;",
|
||||||
" return function() {",
|
" return function() {",
|
||||||
' if (this === Array) return "[Function: Array]";',
|
" var n = this.name;",
|
||||||
' if (this === Object) return "[Function: Object]";',
|
' if (!/^F[0-9]{6}N$/.test(n)) {',
|
||||||
" var i = this.name;",
|
' n = "F" + ++id + "N";',
|
||||||
' if (typeof i != "number") {',
|
|
||||||
" i = ++id;",
|
|
||||||
].concat(Object.getOwnPropertyDescriptor(Function.prototype, "name").configurable ? [
|
].concat(Object.getOwnPropertyDescriptor(Function.prototype, "name").configurable ? [
|
||||||
' Object.defineProperty(this, "name", {',
|
' Object.defineProperty(this, "name", {',
|
||||||
" get: function() {",
|
" get: function() {",
|
||||||
" return i;",
|
" return n;",
|
||||||
" }",
|
" }",
|
||||||
" });",
|
" });",
|
||||||
] : [], [
|
] : [], [
|
||||||
" }",
|
" }",
|
||||||
' return "[Function: " + i + "]";',
|
' return "[Function: " + n + "]";',
|
||||||
" }",
|
" }",
|
||||||
"}();",
|
"}();",
|
||||||
'Object.defineProperty(Function.prototype, "valueOf", { enumerable: false });',
|
'Object.defineProperty(Function.prototype, "valueOf", { enumerable: false });',
|
||||||
@@ -77,7 +83,7 @@ exports.same_stdout = semver.satisfies(process.version, "0.12") ? function(expec
|
|||||||
expected = expected.message.slice(expected.message.lastIndexOf("\n") + 1);
|
expected = expected.message.slice(expected.message.lastIndexOf("\n") + 1);
|
||||||
actual = actual.message.slice(actual.message.lastIndexOf("\n") + 1);
|
actual = actual.message.slice(actual.message.lastIndexOf("\n") + 1);
|
||||||
}
|
}
|
||||||
return expected == actual;
|
return strip_func_ids(expected) == strip_func_ids(actual);
|
||||||
} : function(expected, actual) {
|
} : function(expected, actual) {
|
||||||
return typeof expected == typeof actual && expected.toString() == actual.toString();
|
return typeof expected == typeof actual && strip_func_ids(expected) == strip_func_ids(actual);
|
||||||
};
|
};
|
||||||
|
|||||||
82
test/travis-ufuzz.js
Normal file
82
test/travis-ufuzz.js
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
var child_process = require("child_process");
|
||||||
|
var https = require("https");
|
||||||
|
var url = require("url");
|
||||||
|
|
||||||
|
var period = 45 * 60 * 1000;
|
||||||
|
var wait = 2 * 60 * 1000;
|
||||||
|
var ping = 5 * 60 * 1000;
|
||||||
|
if (process.argv[2] == "run") {
|
||||||
|
var endTime = Date.now() + period;
|
||||||
|
for (var i = 0; i < 2; i++) spawn(endTime);
|
||||||
|
} else if (process.argv.length > 2) {
|
||||||
|
var token = process.argv[2];
|
||||||
|
var branch = process.argv[3] || "v" + require("../package.json").version;
|
||||||
|
var repository = encodeURIComponent(process.argv[4] || "mishoo/UglifyJS2");
|
||||||
|
var concurrency = process.argv[5] || 1;
|
||||||
|
(function request() {
|
||||||
|
setTimeout(request, (period + wait) / concurrency);
|
||||||
|
var options = url.parse("https://api.travis-ci.org/repo/" + repository + "/requests");
|
||||||
|
options.method = "POST";
|
||||||
|
options.headers = {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"Travis-API-Version": 3,
|
||||||
|
"Authorization": "token " + token
|
||||||
|
};
|
||||||
|
https.request(options, function(res) {
|
||||||
|
console.log("HTTP", res.statusCode);
|
||||||
|
console.log(JSON.stringify(res.headers, null, 2));
|
||||||
|
console.log();
|
||||||
|
res.setEncoding("utf8");
|
||||||
|
res.on("data", console.log);
|
||||||
|
}).on("error", console.error).end(JSON.stringify({
|
||||||
|
request: {
|
||||||
|
message: "ufuzz testing (when idle)",
|
||||||
|
branch: branch,
|
||||||
|
config: {
|
||||||
|
merge_mode: "replace",
|
||||||
|
language: "node_js",
|
||||||
|
node_js: "9",
|
||||||
|
sudo: false,
|
||||||
|
script: "node test/travis-ufuzz run"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
})();
|
||||||
|
} else {
|
||||||
|
console.log("Usage: test/travis-ufuzz.js <token> [branch] [repository] [concurrency]");
|
||||||
|
}
|
||||||
|
|
||||||
|
function spawn(endTime) {
|
||||||
|
var child = child_process.spawn("node", [
|
||||||
|
"--max-old-space-size=2048",
|
||||||
|
"test/ufuzz"
|
||||||
|
], {
|
||||||
|
stdio: [ "ignore", "pipe", "pipe" ]
|
||||||
|
}).on("exit", respawn);
|
||||||
|
var line = "";
|
||||||
|
child.stdout.on("data", function(data) {
|
||||||
|
line += data;
|
||||||
|
});
|
||||||
|
child.stderr.on("data", function() {
|
||||||
|
process.exitCode = 1;
|
||||||
|
}).pipe(process.stdout);
|
||||||
|
var keepAlive = setInterval(function() {
|
||||||
|
var end = line.lastIndexOf("\r");
|
||||||
|
console.log(line.slice(line.lastIndexOf("\r", end - 1) + 1, end));
|
||||||
|
line = line.slice(end + 1);
|
||||||
|
}, ping);
|
||||||
|
var timer = setTimeout(function() {
|
||||||
|
clearInterval(keepAlive);
|
||||||
|
child.removeListener("exit", respawn);
|
||||||
|
child.kill();
|
||||||
|
}, endTime - Date.now());
|
||||||
|
|
||||||
|
function respawn() {
|
||||||
|
console.log(line);
|
||||||
|
clearInterval(keepAlive);
|
||||||
|
clearTimeout(timer);
|
||||||
|
spawn(endTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,11 +6,7 @@
|
|||||||
// bin/uglifyjs s.js -c && bin/uglifyjs s.js -c passes=3 && bin/uglifyjs s.js -c passes=3 -m
|
// bin/uglifyjs s.js -c && bin/uglifyjs s.js -c passes=3 && bin/uglifyjs s.js -c passes=3 -m
|
||||||
// cat s.js | node && node s.js && bin/uglifyjs s.js -c | node && bin/uglifyjs s.js -c passes=3 | node && bin/uglifyjs s.js -c passes=3 -m | node
|
// cat s.js | node && node s.js && bin/uglifyjs s.js -c | node && bin/uglifyjs s.js -c passes=3 | node && bin/uglifyjs s.js -c passes=3 -m | node
|
||||||
|
|
||||||
// workaround for tty output truncation upon process.exit()
|
require("../tools/exit");
|
||||||
[process.stdout, process.stderr].forEach(function(stream){
|
|
||||||
if (stream._handle && stream._handle.setBlocking)
|
|
||||||
stream._handle.setBlocking(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
var UglifyJS = require("..");
|
var UglifyJS = require("..");
|
||||||
var randomBytes = require("crypto").randomBytes;
|
var randomBytes = require("crypto").randomBytes;
|
||||||
@@ -127,6 +123,9 @@ for (var i = 2; i < process.argv.length; ++i) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var VALUES = [
|
var VALUES = [
|
||||||
|
'"a"',
|
||||||
|
'"b"',
|
||||||
|
'"c"',
|
||||||
'""',
|
'""',
|
||||||
'true',
|
'true',
|
||||||
'false',
|
'false',
|
||||||
@@ -329,7 +328,8 @@ function createTopLevelCode() {
|
|||||||
rng(2) == 0
|
rng(2) == 0
|
||||||
? createStatements(3, MAX_GENERATION_RECURSION_DEPTH, CANNOT_THROW, CANNOT_BREAK, CANNOT_CONTINUE, CANNOT_RETURN, 0)
|
? createStatements(3, MAX_GENERATION_RECURSION_DEPTH, CANNOT_THROW, CANNOT_BREAK, CANNOT_CONTINUE, CANNOT_RETURN, 0)
|
||||||
: createFunctions(rng(MAX_GENERATED_TOPLEVELS_PER_RUN) + 1, MAX_GENERATION_RECURSION_DEPTH, DEFUN_OK, CANNOT_THROW, 0),
|
: createFunctions(rng(MAX_GENERATED_TOPLEVELS_PER_RUN) + 1, MAX_GENERATION_RECURSION_DEPTH, DEFUN_OK, CANNOT_THROW, 0),
|
||||||
'console.log(null, a, b, c);' // preceding `null` makes for a cleaner output (empty string still shows up etc)
|
// preceding `null` makes for a cleaner output (empty string still shows up etc)
|
||||||
|
'console.log(null, a, b, c, Infinity, NaN, undefined);'
|
||||||
].join('\n');
|
].join('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -635,6 +635,8 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
|
|||||||
case p++:
|
case p++:
|
||||||
case p++:
|
case p++:
|
||||||
return getVarName();
|
return getVarName();
|
||||||
|
case p++:
|
||||||
|
return getVarName() + createAssignment() + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow);
|
||||||
case p++:
|
case p++:
|
||||||
return createExpression(recurmax, COMMA_OK, stmtDepth, canThrow);
|
return createExpression(recurmax, COMMA_OK, stmtDepth, canThrow);
|
||||||
case p++:
|
case p++:
|
||||||
@@ -996,10 +998,11 @@ function log_suspects(minify_options, component) {
|
|||||||
if (typeof options != "object") options = {};
|
if (typeof options != "object") options = {};
|
||||||
var defs = default_options[component];
|
var defs = default_options[component];
|
||||||
var suspects = Object.keys(defs).filter(function(name) {
|
var suspects = Object.keys(defs).filter(function(name) {
|
||||||
if ((name in options ? options : defs)[name]) {
|
var flip = name == "keep_fargs";
|
||||||
|
if (flip ? name in options : (name in options ? options : defs)[name]) {
|
||||||
var m = JSON.parse(JSON.stringify(minify_options));
|
var m = JSON.parse(JSON.stringify(minify_options));
|
||||||
var o = JSON.parse(JSON.stringify(options));
|
var o = JSON.parse(JSON.stringify(options));
|
||||||
o[name] = false;
|
o[name] = flip;
|
||||||
m[component] = o;
|
m[component] = o;
|
||||||
var result = UglifyJS.minify(original_code, m);
|
var result = UglifyJS.minify(original_code, m);
|
||||||
if (result.error) {
|
if (result.error) {
|
||||||
@@ -1020,6 +1023,23 @@ function log_suspects(minify_options, component) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function log_rename(options) {
|
||||||
|
var m = JSON.parse(JSON.stringify(options));
|
||||||
|
m.rename = false;
|
||||||
|
var result = UglifyJS.minify(original_code, m);
|
||||||
|
if (result.error) {
|
||||||
|
errorln("Error testing options.rename");
|
||||||
|
errorln(result.error.stack);
|
||||||
|
} else {
|
||||||
|
var r = sandbox.run_code(result.code);
|
||||||
|
if (sandbox.same_stdout(original_result, r)) {
|
||||||
|
errorln("Suspicious options:");
|
||||||
|
errorln(" rename");
|
||||||
|
errorln();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function log(options) {
|
function log(options) {
|
||||||
if (!ok) errorln('\n\n\n\n\n\n!!!!!!!!!!\n\n\n');
|
if (!ok) errorln('\n\n\n\n\n\n!!!!!!!!!!\n\n\n');
|
||||||
errorln("//=============================================================");
|
errorln("//=============================================================");
|
||||||
@@ -1054,6 +1074,7 @@ function log(options) {
|
|||||||
errorln();
|
errorln();
|
||||||
if (!ok && typeof uglify_code == "string") {
|
if (!ok && typeof uglify_code == "string") {
|
||||||
Object.keys(default_options).forEach(log_suspects.bind(null, options));
|
Object.keys(default_options).forEach(log_suspects.bind(null, options));
|
||||||
|
log_rename(options);
|
||||||
errorln("!!!!!! Failed... round " + round);
|
errorln("!!!!!! Failed... round " + round);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,8 @@
|
|||||||
"output": {
|
"output": {
|
||||||
"beautify": true,
|
"beautify": true,
|
||||||
"bracketize": true
|
"bracketize": true
|
||||||
}
|
},
|
||||||
|
"rename": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"compress": false
|
"compress": false
|
||||||
@@ -20,7 +21,13 @@
|
|||||||
{
|
{
|
||||||
"compress": {
|
"compress": {
|
||||||
"keep_fargs": false,
|
"keep_fargs": false,
|
||||||
"passes": 100
|
"passes": 1e6,
|
||||||
|
"sequences": 1e6,
|
||||||
|
"unsafe": true,
|
||||||
|
"unsafe_Function": true,
|
||||||
|
"unsafe_math": true,
|
||||||
|
"unsafe_proto": true,
|
||||||
|
"unsafe_regexp": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
15
tools/exit.js
Normal file
15
tools/exit.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
// workaround for tty output truncation upon process.exit()
|
||||||
|
var exit = process.exit;
|
||||||
|
process.exit = function() {
|
||||||
|
var args = [].slice.call(arguments);
|
||||||
|
process.once("uncaughtException", function() {
|
||||||
|
(function callback() {
|
||||||
|
if (process.stdout.bufferSize || process.stderr.bufferSize) {
|
||||||
|
setImmediate(callback);
|
||||||
|
} else {
|
||||||
|
exit.apply(process, args);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
});
|
||||||
|
throw exit;
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user