Compare commits
70 Commits
harmony-v3
...
harmony-v3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aebc916215 | ||
|
|
ebf5096864 | ||
|
|
630b09050f | ||
|
|
0cfbd79aa1 | ||
|
|
d66d86f20b | ||
|
|
905325d3e2 | ||
|
|
dea0cc0662 | ||
|
|
d69d8007d6 | ||
|
|
c0b8f2a16d | ||
|
|
cb0257dbbf | ||
|
|
149a569ac8 | ||
|
|
9637f51b68 | ||
|
|
3026bd8975 | ||
|
|
78a44d5ab0 | ||
|
|
4b3c0652b7 | ||
|
|
7e13c0db40 | ||
|
|
e6a2e9e4d0 | ||
|
|
e773f03927 | ||
|
|
b16380d669 | ||
|
|
334b07a3db | ||
|
|
3cc1527f00 | ||
|
|
525a61fb55 | ||
|
|
c3a002ff97 | ||
|
|
fad6766a90 | ||
|
|
aa664dea0a | ||
|
|
102f994b9d | ||
|
|
2a4c68be4f | ||
|
|
541e6011af | ||
|
|
6fa3fbeae8 | ||
|
|
8e595171b9 | ||
|
|
6973abbfe1 | ||
|
|
4eb4cb656c | ||
|
|
193612ac67 | ||
|
|
95cfce68ea | ||
|
|
e0461dc3c8 | ||
|
|
ec4202590d | ||
|
|
5e2cd07d6f | ||
|
|
bea9dbd812 | ||
|
|
bc01a85ba0 | ||
|
|
c7c7960b5f | ||
|
|
fc98d212db | ||
|
|
13accdd745 | ||
|
|
287ec730f7 | ||
|
|
06166df999 | ||
|
|
e2dc9cf091 | ||
|
|
069df27bf1 | ||
|
|
3e7873217c | ||
|
|
e21bab7ce6 | ||
|
|
ac9a168fba | ||
|
|
81b64549ce | ||
|
|
082e004b87 | ||
|
|
983e69128b | ||
|
|
b335912e86 | ||
|
|
cc07f3b806 | ||
|
|
07e4b64f3a | ||
|
|
d3ce2bc9e7 | ||
|
|
cff3bf4914 | ||
|
|
4f57d8746b | ||
|
|
79cfac77bd | ||
|
|
224c14d49d | ||
|
|
7857354d85 | ||
|
|
b4aef753e7 | ||
|
|
424173d311 | ||
|
|
ec7cd1dcf7 | ||
|
|
7def684730 | ||
|
|
10f961c27b | ||
|
|
b483678ca7 | ||
|
|
cbbe6fad60 | ||
|
|
f96929c031 | ||
|
|
2b6657e967 |
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:
|
||||
|
||||
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
|
||||
modification, are permitted provided that the following conditions
|
||||
|
||||
35
README.md
35
README.md
@@ -67,7 +67,7 @@ a double dash to prevent input files being used as option arguments:
|
||||
`debug` Add debug prefix and suffix.
|
||||
`domprops` Mangle property names that overlaps
|
||||
with DOM properties.
|
||||
`keep_quoted` Only mangle unquoted properies.
|
||||
`keep_quoted` Only mangle unquoted properties.
|
||||
`regex` Only mangle matched property names.
|
||||
`reserved` List of names that should not be mangled.
|
||||
-b, --beautify [options] Beautify output/specify output options:
|
||||
@@ -782,7 +782,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
|
||||
`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.
|
||||
|
||||
- `unsafe_math` (default: `false`) -- optimize numerical expressions like
|
||||
@@ -801,6 +801,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
|
||||
`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
|
||||
direct variable assignments do not count as references unless set to `"keep_assign"`)
|
||||
|
||||
@@ -993,9 +997,6 @@ when this flag is on:
|
||||
- `new Object()` → `{}`
|
||||
- `String(exp)` or `exp.toString()` → `"" + exp`
|
||||
- `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
|
||||
|
||||
@@ -1172,3 +1173,27 @@ To enable fast minify mode with the API use:
|
||||
```js
|
||||
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()`).
|
||||
|
||||
@@ -45,6 +45,7 @@ program.option("--ie8", "Support non-standard Internet Explorer 8.");
|
||||
program.option("--keep-classnames", "Do not mangle/drop class names.");
|
||||
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("--rename", "Force symbol expansion.");
|
||||
program.option("--no-rename", "Disable symbol expansion.");
|
||||
program.option("--safari10", "Support non-standard Safari 10.");
|
||||
program.option("--self", "Build UglifyJS as a library (implies --wrap UglifyJS)");
|
||||
@@ -65,14 +66,12 @@ if (!program.output && program.sourceMap && program.sourceMap.url != "inline") {
|
||||
"compress",
|
||||
"ie8",
|
||||
"mangle",
|
||||
"rename",
|
||||
"safari10",
|
||||
"sourceMap",
|
||||
"toplevel",
|
||||
"wrap"
|
||||
].forEach(function(name) {
|
||||
if (name in program) {
|
||||
if (name == "rename" && program[name]) return;
|
||||
options[name] = program[name];
|
||||
}
|
||||
});
|
||||
@@ -132,6 +131,11 @@ if (program.parse) {
|
||||
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) {
|
||||
return name;
|
||||
};
|
||||
|
||||
14
lib/ast.js
14
lib/ast.js
@@ -267,11 +267,10 @@ var AST_For = DEFNODE("For", "init condition step", {
|
||||
}
|
||||
}, AST_IterationStatement);
|
||||
|
||||
var AST_ForIn = DEFNODE("ForIn", "init name object", {
|
||||
var AST_ForIn = DEFNODE("ForIn", "init object", {
|
||||
$documentation: "A `for ... in` statement",
|
||||
$propdoc: {
|
||||
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"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
@@ -319,6 +318,13 @@ var AST_Scope = DEFNODE("Scope", "variables functions uses_with uses_eval parent
|
||||
self = self.parent_scope;
|
||||
}
|
||||
return self;
|
||||
},
|
||||
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);
|
||||
|
||||
@@ -863,8 +869,8 @@ var AST_Object = DEFNODE("Object", "properties", {
|
||||
var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", {
|
||||
$documentation: "Base class for literal object properties",
|
||||
$propdoc: {
|
||||
key: "[string|AST_Node] the property name converted to a string for ObjectKeyVal. For setters, getters and computed property this is an arbitrary AST_Node",
|
||||
value: "[AST_Node] property value. For setters and getters this is an AST_Accessor."
|
||||
key: "[string|AST_Node] property name. For ObjectKeyVal this is a string. For getters, setters and computed property this is an AST_Node.",
|
||||
value: "[AST_Node] property value. For getters and setters this is an AST_Accessor."
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
|
||||
692
lib/compress.js
692
lib/compress.js
File diff suppressed because it is too large
Load Diff
@@ -151,7 +151,9 @@ function minify(files, options) {
|
||||
toplevel = toplevel.wrap_commonjs(options.wrap);
|
||||
}
|
||||
if (timings) timings.rename = Date.now();
|
||||
if (options.rename) {
|
||||
// disable rename on harmony due to expand_names bug in for-of loops
|
||||
// https://github.com/mishoo/UglifyJS2/issues/2794
|
||||
if (0 && options.rename) {
|
||||
toplevel.figure_out_scope(options.mangle);
|
||||
toplevel.expand_names(options.mangle);
|
||||
}
|
||||
|
||||
@@ -472,6 +472,11 @@ function OutputStream(options) {
|
||||
return OUTPUT;
|
||||
};
|
||||
|
||||
function has_nlb() {
|
||||
var index = OUTPUT.lastIndexOf("\n");
|
||||
return /^ *$/.test(OUTPUT.slice(index + 1));
|
||||
}
|
||||
|
||||
function prepend_comments(node) {
|
||||
var self = this;
|
||||
var start = node.start;
|
||||
@@ -521,7 +526,7 @@ function OutputStream(options) {
|
||||
|
||||
comments = comments.filter(comment_filter, node);
|
||||
if (comments.length == 0) return;
|
||||
var last_nlb = /(^|\n) *$/.test(OUTPUT);
|
||||
var last_nlb = has_nlb();
|
||||
comments.forEach(function(c, i) {
|
||||
if (!last_nlb) {
|
||||
if (c.nlb) {
|
||||
@@ -568,7 +573,7 @@ function OutputStream(options) {
|
||||
print("\n");
|
||||
indent();
|
||||
need_newline_indented = false;
|
||||
} else if (c.nlb && (i > 0 || !/(^|\n) *$/.test(OUTPUT))) {
|
||||
} else if (c.nlb && (i > 0 || !has_nlb())) {
|
||||
print("\n");
|
||||
indent();
|
||||
} else if (i > 0 || !tail) {
|
||||
@@ -766,6 +771,8 @@ function OutputStream(options) {
|
||||
|| p instanceof AST_Arrow // x => (x, x)
|
||||
|| p instanceof AST_DefaultAssign // x => (x = (0, function(){}))
|
||||
|| p instanceof AST_Expansion // [...(a, b)]
|
||||
|| p instanceof AST_ForOf && this === p.object // for (e of (foo, bar)) {}
|
||||
|| p instanceof AST_Yield // yield (foo, bar)
|
||||
;
|
||||
});
|
||||
|
||||
@@ -1046,11 +1053,7 @@ function OutputStream(options) {
|
||||
output.with_parens(function(){
|
||||
self.init.print(output);
|
||||
output.space();
|
||||
if (self instanceof AST_ForOf) {
|
||||
output.print("of");
|
||||
} else {
|
||||
output.print("in");
|
||||
}
|
||||
output.print(self instanceof AST_ForOf ? "of" : "in");
|
||||
output.space();
|
||||
self.object.print(output);
|
||||
});
|
||||
@@ -1680,11 +1683,8 @@ function OutputStream(options) {
|
||||
|
||||
function print_property_name(key, quote, output) {
|
||||
if (output.option("quote_keys")) {
|
||||
output.print_string(key + "");
|
||||
} else if ((typeof key == "number"
|
||||
|| !output.option("beautify")
|
||||
&& +key + "" == key)
|
||||
&& parseFloat(key) >= 0) {
|
||||
output.print_string(key);
|
||||
} else if ("" + +key == key && key >= 0) {
|
||||
output.print(make_num(key));
|
||||
} else if (RESERVED_WORDS(key) ? !output.option("ie8") : is_identifier_string(key)) {
|
||||
if (quote && output.option("keep_quoted_props")) {
|
||||
|
||||
@@ -1276,12 +1276,10 @@ function parse($TEXT, options) {
|
||||
};
|
||||
|
||||
function for_in(init) {
|
||||
var lhs = init instanceof AST_Definitions ? init.definitions[0].name : null;
|
||||
var obj = expression(true);
|
||||
expect(")");
|
||||
return new AST_ForIn({
|
||||
init : init,
|
||||
name : lhs,
|
||||
object : obj,
|
||||
body : in_loop(statement)
|
||||
});
|
||||
@@ -2226,7 +2224,7 @@ function parse($TEXT, options) {
|
||||
a.push(new AST_ObjectKeyVal({
|
||||
start: start,
|
||||
quote: start.quote,
|
||||
key: name,
|
||||
key: name instanceof AST_Node ? name : "" + name,
|
||||
value: value,
|
||||
end: prev()
|
||||
}));
|
||||
@@ -2283,7 +2281,7 @@ function parse($TEXT, options) {
|
||||
if (typeof name === "string" || typeof name === "number") {
|
||||
return new AST_SymbolMethod({
|
||||
start: token,
|
||||
name: name,
|
||||
name: "" + name,
|
||||
end: prev()
|
||||
});
|
||||
} else if (name === null) {
|
||||
|
||||
@@ -383,6 +383,11 @@ AST_Lambda.DEFMETHOD("init_scope_vars", function(){
|
||||
}));
|
||||
});
|
||||
|
||||
AST_Arrow.DEFMETHOD("init_scope_vars", function(){
|
||||
AST_Scope.prototype.init_scope_vars.apply(this, arguments);
|
||||
this.uses_arguments = false;
|
||||
});
|
||||
|
||||
AST_Symbol.DEFMETHOD("mark_enclosed", function(options) {
|
||||
var def = this.definition();
|
||||
var s = this.scope;
|
||||
@@ -411,7 +416,7 @@ AST_Scope.DEFMETHOD("find_variable", function(name){
|
||||
|
||||
AST_Scope.DEFMETHOD("def_function", function(symbol, init){
|
||||
var def = this.def_variable(symbol, init);
|
||||
if (!def.init) def.init = init;
|
||||
if (!def.init || def.init instanceof AST_Defun) def.init = init;
|
||||
this.functions.set(symbol.name, def);
|
||||
return def;
|
||||
});
|
||||
|
||||
@@ -303,6 +303,13 @@ Dictionary.prototype = {
|
||||
ret.push(f(this._values[i], i.substr(1)));
|
||||
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 }
|
||||
};
|
||||
Dictionary.fromObject = function(obj) {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"homepage": "https://github.com/mishoo/UglifyJS2/tree/harmony",
|
||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||
"license": "BSD-2-Clause",
|
||||
"version": "3.3.7",
|
||||
"version": "3.3.10",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
},
|
||||
@@ -24,13 +24,13 @@
|
||||
"LICENSE"
|
||||
],
|
||||
"dependencies": {
|
||||
"commander": "~2.13.0",
|
||||
"commander": "~2.14.1",
|
||||
"source-map": "~0.6.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"acorn": "~5.3.0",
|
||||
"acorn": "~5.4.1",
|
||||
"mocha": "~3.5.1",
|
||||
"semver": "~5.4.1"
|
||||
"semver": "~5.5.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "node test/run-tests.js"
|
||||
|
||||
@@ -75,6 +75,7 @@ issue_1664: {
|
||||
}
|
||||
expect_stdout: "1"
|
||||
node_version: ">=6"
|
||||
reminify: false // FIXME - block scoped function
|
||||
}
|
||||
|
||||
issue_1672_for: {
|
||||
|
||||
@@ -52,13 +52,8 @@ collapse_vars_side_effects_1: {
|
||||
console.log.bind(console)(s.charAt(i++), s.charAt(i++), s.charAt(i++), 7);
|
||||
}
|
||||
function f2() {
|
||||
var log = console.log.bind(console),
|
||||
s = "abcdef",
|
||||
i = 2,
|
||||
x = s.charAt(i++),
|
||||
y = s.charAt(i++),
|
||||
z = s.charAt(i++);
|
||||
log(x, i, y, z, 7);
|
||||
var s = "abcdef", i = 2;
|
||||
console.log.bind(console)(s.charAt(i++), 5, s.charAt(i++), s.charAt(i++), 7);
|
||||
}
|
||||
function f3() {
|
||||
var s = "abcdef",
|
||||
@@ -72,7 +67,7 @@ collapse_vars_side_effects_1: {
|
||||
var i = 10,
|
||||
x = i += 2,
|
||||
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();
|
||||
}
|
||||
@@ -4314,3 +4309,513 @@ replace_all_var: {
|
||||
}
|
||||
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"
|
||||
}
|
||||
|
||||
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"
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@ dead_code_2_should_warn: {
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=6"
|
||||
reminify: false // FIXME - block scoped function
|
||||
}
|
||||
|
||||
dead_code_2_should_warn_strict: {
|
||||
@@ -100,6 +101,7 @@ dead_code_2_should_warn_strict: {
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=4"
|
||||
reminify: false // FIXME - block scoped function
|
||||
}
|
||||
|
||||
dead_code_constant_boolean_should_warn_more: {
|
||||
@@ -135,6 +137,7 @@ dead_code_constant_boolean_should_warn_more: {
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=6"
|
||||
reminify: false // FIXME - block scoped function
|
||||
}
|
||||
|
||||
dead_code_constant_boolean_should_warn_more_strict: {
|
||||
@@ -171,6 +174,7 @@ dead_code_constant_boolean_should_warn_more_strict: {
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=4"
|
||||
reminify: false // FIXME - block scoped function
|
||||
}
|
||||
|
||||
dead_code_block_decls_die: {
|
||||
@@ -1157,3 +1161,58 @@ issue_2749: {
|
||||
}
|
||||
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"
|
||||
}
|
||||
|
||||
@@ -2066,3 +2066,30 @@ issue_2768: {
|
||||
}
|
||||
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"
|
||||
}
|
||||
|
||||
@@ -1287,6 +1287,9 @@ issue_2231_1: {
|
||||
console.log(Object.keys(void 0));
|
||||
}
|
||||
expect_stdout: true
|
||||
expect_warnings: [
|
||||
"WARN: Error evaluating Object.keys(void 0) [test/compress/evaluate.js:1284,20]",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2231_2: {
|
||||
@@ -1301,6 +1304,23 @@ issue_2231_2: {
|
||||
console.log(Object.getOwnPropertyNames(null));
|
||||
}
|
||||
expect_stdout: true
|
||||
expect_warnings: [
|
||||
"WARN: Error evaluating Object.getOwnPropertyNames(null) [test/compress/evaluate.js:1301,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: {
|
||||
@@ -1423,13 +1443,82 @@ issue_2535_3: {
|
||||
}
|
||||
expect_stdout: true
|
||||
expect_warnings: [
|
||||
"WARN: Dropping side-effect-free && [test/compress/evaluate.js:1409,20]",
|
||||
"WARN: Dropping side-effect-free && [test/compress/evaluate.js:1410,20]",
|
||||
"WARN: Dropping side-effect-free && [test/compress/evaluate.js:1411,20]",
|
||||
"WARN: Condition left of && always false [test/compress/evaluate.js:1411,20]",
|
||||
"WARN: Dropping side-effect-free || [test/compress/evaluate.js:1412,20]",
|
||||
"WARN: Dropping side-effect-free || [test/compress/evaluate.js:1413,20]",
|
||||
"WARN: Dropping side-effect-free || [test/compress/evaluate.js:1414,20]",
|
||||
"WARN: Condition left of || always true [test/compress/evaluate.js:1414,20]",
|
||||
"WARN: Dropping side-effect-free && [test/compress/evaluate.js:1429,20]",
|
||||
"WARN: Dropping side-effect-free && [test/compress/evaluate.js:1430,20]",
|
||||
"WARN: Dropping side-effect-free && [test/compress/evaluate.js:1431,20]",
|
||||
"WARN: Condition left of && always false [test/compress/evaluate.js:1431,20]",
|
||||
"WARN: Dropping side-effect-free || [test/compress/evaluate.js:1432,20]",
|
||||
"WARN: Dropping side-effect-free || [test/compress/evaluate.js:1433,20]",
|
||||
"WARN: Dropping side-effect-free || [test/compress/evaluate.js:1434,20]",
|
||||
"WARN: Condition left of || always true [test/compress/evaluate.js:1434,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",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -258,7 +258,7 @@ issue_203: {
|
||||
options = {
|
||||
keep_fargs: false,
|
||||
side_effects: true,
|
||||
unsafe_Func: true,
|
||||
unsafe_Function: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
@@ -1516,9 +1516,11 @@ issue_2647_2: {
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
console.log((() => (x = "pass", x.toUpperCase()))());
|
||||
var x;
|
||||
})();
|
||||
function foo(x) {
|
||||
return x.toUpperCase();
|
||||
}
|
||||
console.log((() => foo("pass"))());
|
||||
}());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
@@ -2117,3 +2119,41 @@ issue_2737_2: {
|
||||
}
|
||||
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"
|
||||
}
|
||||
|
||||
@@ -1245,3 +1245,359 @@ issue_2762: {
|
||||
}
|
||||
expect_stdout: "1 2 3"
|
||||
}
|
||||
|
||||
issue_2794_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
passes: 1,
|
||||
properties: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: false,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function foo() {
|
||||
for (const a of func(value)) {
|
||||
console.log(a);
|
||||
}
|
||||
function func(va) {
|
||||
return doSomething(va);
|
||||
}
|
||||
}
|
||||
function doSomething(x) {
|
||||
return [ x, 2 * x, 3 * x ];
|
||||
}
|
||||
const value = 10;
|
||||
foo();
|
||||
}
|
||||
expect: {
|
||||
function foo() {
|
||||
for (const a of doSomething(value)) console.log(a);
|
||||
}
|
||||
function doSomething(x) {
|
||||
return [ x, 2 * x, 3 * x ];
|
||||
}
|
||||
const value = 10;
|
||||
foo();
|
||||
}
|
||||
expect_stdout: [
|
||||
"10",
|
||||
"20",
|
||||
"30",
|
||||
]
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_2794_2: {
|
||||
mangle = {
|
||||
toplevel: false,
|
||||
}
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
passes: 1,
|
||||
properties: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: false,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function foo() {
|
||||
for (const a of func(value)) {
|
||||
console.log(a);
|
||||
}
|
||||
function func(va) {
|
||||
return doSomething(va);
|
||||
}
|
||||
}
|
||||
function doSomething(x) {
|
||||
return [ x, 2 * x, 3 * x ];
|
||||
}
|
||||
const value = 10;
|
||||
foo();
|
||||
}
|
||||
expect: {
|
||||
function foo() {
|
||||
for (const o of doSomething(value)) console.log(o);
|
||||
}
|
||||
function doSomething(o) {
|
||||
return [ o, 2 * o, 3 * o ];
|
||||
}
|
||||
const value = 10;
|
||||
foo();
|
||||
}
|
||||
expect_stdout: [
|
||||
"10",
|
||||
"20",
|
||||
"30",
|
||||
]
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_2794_3: {
|
||||
mangle = {
|
||||
toplevel: true,
|
||||
}
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
inline: 3,
|
||||
passes: 3,
|
||||
properties: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function foo() {
|
||||
for (const a of func(value)) {
|
||||
console.log(a);
|
||||
}
|
||||
function func(va) {
|
||||
return doSomething(va);
|
||||
}
|
||||
}
|
||||
function doSomething(x) {
|
||||
return [ x, 2 * x, 3 * x ];
|
||||
}
|
||||
const value = 10;
|
||||
foo();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
for (const o of [ 10, 20, 30 ]) console.log(o);
|
||||
})();
|
||||
}
|
||||
expect_stdout: [
|
||||
"10",
|
||||
"20",
|
||||
"30",
|
||||
]
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_2794_4: {
|
||||
options = {}
|
||||
input: {
|
||||
for (var x of ([1, 2], [3, 4])) {
|
||||
console.log(x);
|
||||
}
|
||||
}
|
||||
expect_exact: "for(var x of([1,2],[3,4]))console.log(x);"
|
||||
expect_stdout: [
|
||||
"3",
|
||||
"4",
|
||||
]
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_2794_5: {
|
||||
mangle = {}
|
||||
options = {
|
||||
evaluate: true,
|
||||
passes: 1,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
for (var x of ([1, 2], [3, 4])) {
|
||||
console.log(x);
|
||||
}
|
||||
}
|
||||
expect_exact: "for(var x of[3,4])console.log(x);"
|
||||
expect_stdout: [
|
||||
"3",
|
||||
"4",
|
||||
]
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_2794_6: {
|
||||
options = {
|
||||
}
|
||||
input: {
|
||||
// TODO (or not): have parser flag invalid for-of expression.
|
||||
// Consider it an uglify extension in the meantime.
|
||||
for (let e of [1,2], [3,4,5]) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_exact: "for(let e of([1,2],[3,4,5]))console.log(e);"
|
||||
expect_stdout: [
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
]
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
inline_arrow_using_arguments: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: 1,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(){
|
||||
((x) => {
|
||||
console.log.apply(console, arguments),
|
||||
console.log(x);
|
||||
})(4);
|
||||
})(3, 2, 1);
|
||||
}
|
||||
expect: {
|
||||
(function(){
|
||||
console.log.apply(console, arguments),
|
||||
console.log(4);
|
||||
})(3, 2, 1);
|
||||
}
|
||||
expect_stdout: [
|
||||
"3 2 1",
|
||||
"4",
|
||||
]
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_2874_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
inline: 3,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
function foo() {
|
||||
let letters = ["A", "B", "C"];
|
||||
let result = [2, 1, 0].map(key => bar(letters[key] + key));
|
||||
return result;
|
||||
}
|
||||
function bar(value) {
|
||||
return () => console.log(value);
|
||||
}
|
||||
foo().map(fn => fn());
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
(function() {
|
||||
let letters = [ "A", "B", "C" ];
|
||||
return [ 2, 1, 0 ].map(key => (function(value) {
|
||||
return () => console.log(value);
|
||||
})(letters[key] + key));
|
||||
})().map(fn => fn());
|
||||
})();
|
||||
}
|
||||
expect_stdout: [
|
||||
"C2",
|
||||
"B1",
|
||||
"A0",
|
||||
]
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_2874_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
inline: 3,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
let keys = [];
|
||||
function foo() {
|
||||
var result = [2, 1, 0].map(value => {
|
||||
keys.push(value);
|
||||
return bar();
|
||||
});
|
||||
return result;
|
||||
}
|
||||
function bar() {
|
||||
var letters = ["A", "B", "C"], key = keys.shift();
|
||||
return () => console.log(letters[key] + key);
|
||||
}
|
||||
foo().map(fn => fn());
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
let keys = [];
|
||||
[ 2, 1, 0 ].map(value => {
|
||||
return keys.push(value), function() {
|
||||
var letters = [ "A", "B", "C" ], key = keys.shift();
|
||||
return () => console.log(letters[key] + key);
|
||||
}();
|
||||
}).map(fn => fn());
|
||||
})();
|
||||
}
|
||||
expect_stdout: [
|
||||
"C2",
|
||||
"B1",
|
||||
"A0",
|
||||
]
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_2874_3: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
inline: 3,
|
||||
reduce_funcs: false,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
return x + y;
|
||||
}
|
||||
let x, y;
|
||||
let a = (z) => {
|
||||
x = "A";
|
||||
y = z;
|
||||
console.log(f());
|
||||
}
|
||||
a(1);
|
||||
a(2);
|
||||
}
|
||||
expect: {
|
||||
let x, y;
|
||||
let a = z => {
|
||||
x = "A",
|
||||
y = z,
|
||||
console.log(x + y);
|
||||
};
|
||||
a(1),
|
||||
a(2);
|
||||
}
|
||||
expect_stdout: [
|
||||
"A1",
|
||||
"A2",
|
||||
]
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
@@ -897,3 +897,25 @@ toplevel_var: {
|
||||
}
|
||||
expect_stdout: "3"
|
||||
}
|
||||
|
||||
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"
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ unsafe_undefined: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
unsafe: true
|
||||
unsafe_undefined: true,
|
||||
}
|
||||
mangle = {}
|
||||
input: {
|
||||
@@ -30,7 +30,7 @@ keep_fnames: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
unsafe: true
|
||||
unsafe_undefined: true,
|
||||
}
|
||||
mangle = {
|
||||
keep_fnames: true
|
||||
|
||||
@@ -38,6 +38,7 @@ same_variable_in_multiple_for_loop: {
|
||||
}
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
same_variable_in_multiple_forOf: {
|
||||
@@ -79,6 +80,7 @@ same_variable_in_multiple_forOf: {
|
||||
}
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
same_variable_in_multiple_forIn: {
|
||||
@@ -120,6 +122,7 @@ same_variable_in_multiple_forIn: {
|
||||
}
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
different_variable_in_multiple_for_loop: {
|
||||
@@ -162,6 +165,7 @@ different_variable_in_multiple_for_loop: {
|
||||
}
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
different_variable_in_multiple_forOf: {
|
||||
@@ -203,6 +207,7 @@ different_variable_in_multiple_forOf: {
|
||||
}
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
different_variable_in_multiple_forIn: {
|
||||
@@ -244,6 +249,175 @@ different_variable_in_multiple_forIn: {
|
||||
}
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
same_variable_in_multiple_forOf_sequences_let: {
|
||||
options = {
|
||||
hoist_funs: true,
|
||||
dead_code: true,
|
||||
conditionals: true,
|
||||
comparisons: true,
|
||||
evaluate: true,
|
||||
booleans: true,
|
||||
loops: true,
|
||||
unused: true,
|
||||
keep_fargs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
collapse_vars: true,
|
||||
}
|
||||
mangle = {}
|
||||
input: {
|
||||
var test = [ "a", "b", "c" ];
|
||||
for (let tmp of test) {
|
||||
console.log(tmp);
|
||||
let dd;
|
||||
dd = [ "e", "f", "g" ];
|
||||
for (let tmp of dd) {
|
||||
console.log(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var test = [ "a", "b", "c" ];
|
||||
for (let o of test) {
|
||||
let e;
|
||||
console.log(o), e = [ "e", "f", "g" ];
|
||||
for (let o of e)
|
||||
console.log(o);
|
||||
}
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
same_variable_in_multiple_forOf_sequences_const: {
|
||||
options = {
|
||||
hoist_funs: true,
|
||||
dead_code: true,
|
||||
conditionals: true,
|
||||
comparisons: true,
|
||||
evaluate: true,
|
||||
booleans: true,
|
||||
loops: true,
|
||||
unused: true,
|
||||
keep_fargs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
collapse_vars: true,
|
||||
}
|
||||
mangle = {}
|
||||
input: {
|
||||
var test = [ "a", "b", "c" ];
|
||||
for (const tmp of test) {
|
||||
console.log(tmp);
|
||||
let dd;
|
||||
dd = [ "e", "f", "g" ];
|
||||
for (const tmp of dd) {
|
||||
console.log(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var test = [ "a", "b", "c" ];
|
||||
for (const o of test) {
|
||||
let t;
|
||||
console.log(o), t = [ "e", "f", "g" ];
|
||||
for (const o of t)
|
||||
console.log(o);
|
||||
}
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
same_variable_in_multiple_forIn_sequences_let: {
|
||||
options = {
|
||||
hoist_funs: true,
|
||||
dead_code: true,
|
||||
conditionals: true,
|
||||
comparisons: true,
|
||||
evaluate: true,
|
||||
booleans: true,
|
||||
loops: true,
|
||||
unused: false,
|
||||
keep_fargs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
collapse_vars: true,
|
||||
}
|
||||
mangle = {}
|
||||
input: {
|
||||
var test = [ "a", "b", "c" ];
|
||||
for (let tmp in test) {
|
||||
console.log(tmp);
|
||||
let dd;
|
||||
dd = [ "e", "f", "g" ];
|
||||
for (let tmp in test) {
|
||||
console.log(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var test = [ "a", "b", "c" ];
|
||||
for (let e in test) {
|
||||
let t;
|
||||
console.log(e), t = [ "e", "f", "g" ];
|
||||
for (let e in test)
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
same_variable_in_multiple_forIn_sequences_const: {
|
||||
options = {
|
||||
hoist_funs: true,
|
||||
dead_code: true,
|
||||
conditionals: true,
|
||||
comparisons: true,
|
||||
evaluate: true,
|
||||
booleans: true,
|
||||
loops: true,
|
||||
unused: false,
|
||||
keep_fargs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
collapse_vars: true,
|
||||
}
|
||||
mangle = {}
|
||||
input: {
|
||||
var test = [ "a", "b", "c" ];
|
||||
for (const tmp in test) {
|
||||
console.log(tmp);
|
||||
let dd;
|
||||
dd = [ "e", "f", "g" ];
|
||||
for (const tmp in test) {
|
||||
console.log(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var test = [ "a", "b", "c" ];
|
||||
for (const o in test) {
|
||||
let t;
|
||||
console.log(o), t = [ "e", "f", "g" ];
|
||||
for (const o in test)
|
||||
console.log(o);
|
||||
}
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
more_variable_in_multiple_for: {
|
||||
@@ -281,4 +455,5 @@ more_variable_in_multiple_for: {
|
||||
}
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ unsafe_undefined: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
unsafe: true,
|
||||
unsafe_undefined: true,
|
||||
}
|
||||
mangle = {}
|
||||
input: {
|
||||
|
||||
@@ -84,12 +84,12 @@ numeric_literal: {
|
||||
' 0: 0,',
|
||||
' "-0": 1,',
|
||||
' 42: 2,',
|
||||
' "42": 3,',
|
||||
' 42: 3,',
|
||||
' 37: 4,',
|
||||
' o: 5,',
|
||||
' 1e42: 6,',
|
||||
' b: 7,',
|
||||
' "1e+42": 8',
|
||||
' 1e42: 8',
|
||||
'};',
|
||||
'',
|
||||
'console.log(obj[-0], obj[-""], obj["-0"]);',
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
compress_new_function: {
|
||||
options = {
|
||||
unsafe: true,
|
||||
unsafe_Func: true,
|
||||
unsafe_Function: true,
|
||||
}
|
||||
input: {
|
||||
new Function("aa, bb", 'return aa;');
|
||||
@@ -15,7 +15,7 @@ compress_new_function: {
|
||||
compress_new_function_with_destruct: {
|
||||
options = {
|
||||
unsafe: true,
|
||||
unsafe_Func: true,
|
||||
unsafe_Function: true,
|
||||
ecma: 6
|
||||
}
|
||||
beautify = {
|
||||
@@ -38,7 +38,7 @@ compress_new_function_with_destruct_arrows: {
|
||||
arrows: true,
|
||||
unsafe_arrows: true,
|
||||
unsafe: true,
|
||||
unsafe_Func: true,
|
||||
unsafe_Function: true,
|
||||
ecma: 6,
|
||||
}
|
||||
beautify = {
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -585,6 +585,25 @@ native_prototype: {
|
||||
}
|
||||
}
|
||||
|
||||
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: {
|
||||
input: {
|
||||
var a = 1;
|
||||
@@ -1466,7 +1485,7 @@ join_object_assignments_3: {
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
join_object_assignments_4: {
|
||||
join_object_assignments_return_1: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
}
|
||||
@@ -1490,7 +1509,7 @@ join_object_assignments_4: {
|
||||
expect_stdout: "foo"
|
||||
}
|
||||
|
||||
join_object_assignments_5: {
|
||||
join_object_assignments_return_2: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
}
|
||||
@@ -1516,7 +1535,7 @@ join_object_assignments_5: {
|
||||
expect_stdout: "bar"
|
||||
}
|
||||
|
||||
join_object_assignments_6: {
|
||||
join_object_assignments_return_3: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
}
|
||||
@@ -1548,7 +1567,7 @@ join_object_assignments_6: {
|
||||
]
|
||||
}
|
||||
|
||||
join_object_assignments_7: {
|
||||
join_object_assignments_for: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
}
|
||||
@@ -1575,3 +1594,303 @@ join_object_assignments_7: {
|
||||
"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"
|
||||
}
|
||||
|
||||
issue_2816_ecma6: {
|
||||
options = {
|
||||
ecma: "6",
|
||||
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,
|
||||
a: 3,
|
||||
c: 4
|
||||
};
|
||||
console.log(o.a, o.b, o.c);
|
||||
}
|
||||
expect_stdout: "3 2 4"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
@@ -818,3 +818,30 @@ issue_2678: {
|
||||
}
|
||||
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(b + 1);
|
||||
}
|
||||
|
||||
function f1() {
|
||||
var a = 1, b = 2;
|
||||
--b;
|
||||
console.log(a + 1);
|
||||
console.log(b + 1);
|
||||
}
|
||||
|
||||
function f2() {
|
||||
var a = 1, b = 2, c = 3;
|
||||
b = c;
|
||||
@@ -92,7 +90,6 @@ modified: {
|
||||
console.log(a + c);
|
||||
console.log(a + b + c);
|
||||
}
|
||||
|
||||
function f3() {
|
||||
var a = 1, b = 2, c = 3;
|
||||
b *= c;
|
||||
@@ -101,7 +98,6 @@ modified: {
|
||||
console.log(a + c);
|
||||
console.log(a + b + c);
|
||||
}
|
||||
|
||||
function f4() {
|
||||
var a = 1, b = 2, c = 3;
|
||||
if (a) {
|
||||
@@ -114,28 +110,26 @@ modified: {
|
||||
console.log(a + c);
|
||||
console.log(a + b + c);
|
||||
}
|
||||
|
||||
function f5(a) {
|
||||
B = a;
|
||||
console.log(A ? 'yes' : 'no');
|
||||
console.log(B ? 'yes' : 'no');
|
||||
console.log(typeof A ? "yes" : "no");
|
||||
console.log(typeof B ? "yes" : "no");
|
||||
}
|
||||
f0(), f1(), f2(), f3(), f4(), f5();
|
||||
}
|
||||
expect: {
|
||||
function f0() {
|
||||
var b = 2;
|
||||
b++;
|
||||
console.log(2);
|
||||
console.log(b + 1);
|
||||
console.log(4);
|
||||
}
|
||||
|
||||
function f1() {
|
||||
var b = 2;
|
||||
--b;
|
||||
console.log(2);
|
||||
console.log(b + 1);
|
||||
console.log(2);
|
||||
}
|
||||
|
||||
function f2() {
|
||||
3;
|
||||
console.log(4);
|
||||
@@ -143,16 +137,14 @@ modified: {
|
||||
console.log(4);
|
||||
console.log(7);
|
||||
}
|
||||
|
||||
function f3() {
|
||||
var b = 2;
|
||||
b *= 3;
|
||||
console.log(1 + b);
|
||||
console.log(b + 3);
|
||||
console.log(7);
|
||||
console.log(9);
|
||||
console.log(4);
|
||||
console.log(1 + b + 3);
|
||||
console.log(10);
|
||||
}
|
||||
|
||||
function f4() {
|
||||
var b = 2, c = 3;
|
||||
b = c;
|
||||
@@ -161,13 +153,33 @@ modified: {
|
||||
console.log(1 + c);
|
||||
console.log(1 + b + c);
|
||||
}
|
||||
|
||||
function f5(a) {
|
||||
B = a;
|
||||
console.log(A ? 'yes' : 'no');
|
||||
console.log(B ? 'yes' : 'no');
|
||||
console.log(typeof A ? "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: {
|
||||
@@ -745,7 +757,7 @@ iife: {
|
||||
expect: {
|
||||
!function(a, b, c) {
|
||||
b++;
|
||||
console.log(0, 1 * b, 5);
|
||||
console.log(0, 3, 5);
|
||||
}(1, 2, 3);
|
||||
}
|
||||
expect_stdout: true
|
||||
@@ -766,7 +778,7 @@ iife_new: {
|
||||
expect: {
|
||||
var A = new function(a, b, c) {
|
||||
b++;
|
||||
console.log(0, 1 * b, 5);
|
||||
console.log(0, 3, 5);
|
||||
}(1, 2, 3);
|
||||
}
|
||||
expect_stdout: true
|
||||
@@ -5892,3 +5904,222 @@ issue_2774: {
|
||||
}
|
||||
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,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unsafe: true,
|
||||
unsafe_undefined: true,
|
||||
}
|
||||
input: {
|
||||
function f(undefined) {
|
||||
@@ -883,3 +883,21 @@ for_init_var: {
|
||||
}
|
||||
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"
|
||||
}
|
||||
|
||||
@@ -211,3 +211,43 @@ issue_2689: {
|
||||
}
|
||||
expect_exact: "function*y(){return new(yield x())}"
|
||||
}
|
||||
|
||||
issue_2832: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
}
|
||||
input: {
|
||||
function* gen(i) {
|
||||
const result = yield (x = i, -x);
|
||||
var x;
|
||||
console.log(x);
|
||||
console.log(result);
|
||||
yield 2;
|
||||
}
|
||||
var x = gen(1);
|
||||
console.log(x.next("first").value);
|
||||
console.log(x.next("second").value);
|
||||
}
|
||||
expect_exact: [
|
||||
"function* gen(i) {",
|
||||
" const result = yield (x = i, -x);",
|
||||
" var x;",
|
||||
" console.log(x);",
|
||||
" console.log(result);",
|
||||
" yield 2;",
|
||||
"}",
|
||||
"",
|
||||
"var x = gen(1);",
|
||||
"",
|
||||
'console.log(x.next("first").value);',
|
||||
"",
|
||||
'console.log(x.next("second").value);',
|
||||
]
|
||||
expect_stdout: [
|
||||
"-1",
|
||||
"1",
|
||||
"second",
|
||||
"2",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,29 +1,24 @@
|
||||
var Mocha = require('mocha'),
|
||||
fs = require('fs'),
|
||||
path = require('path');
|
||||
var fs = require("fs");
|
||||
var Mocha = require("mocha");
|
||||
var path = require("path");
|
||||
|
||||
// Instantiate a Mocha instance.
|
||||
var mocha = new Mocha({});
|
||||
// Instantiate a Mocha instance
|
||||
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){
|
||||
// Only keep the .js files
|
||||
return file.substr(-3) === '.js';
|
||||
|
||||
}).forEach(function(file){
|
||||
mocha.addFile(
|
||||
path.join(testDir, file)
|
||||
);
|
||||
// Add each .js file to the Mocha instance
|
||||
fs.readdirSync(testDir).filter(function(file) {
|
||||
return /\.js$/.test(file);
|
||||
}).forEach(function(file) {
|
||||
mocha.addFile(path.join(testDir, file));
|
||||
});
|
||||
|
||||
module.exports = function() {
|
||||
mocha.run(function(failures) {
|
||||
if (failures !== 0) {
|
||||
process.on('exit', function () {
|
||||
process.exit(failures);
|
||||
});
|
||||
}
|
||||
if (failures) process.on("exit", function() {
|
||||
process.exit(failures);
|
||||
});
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
@@ -405,7 +405,8 @@ describe("minify", function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe("rename", function() {
|
||||
// rename is disabled on harmony due to expand_names bug in for-of loops
|
||||
if (0) describe("rename", function() {
|
||||
it("Should be repeatable", function() {
|
||||
var code = "!function(x){return x(x)}(y);";
|
||||
for (var i = 0; i < 2; i++) {
|
||||
|
||||
@@ -208,6 +208,9 @@ function run_compress_tests() {
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (0 && test.reminify && !reminify(test.options, input_code, input_formatted, test.expect_stdout)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -261,6 +264,16 @@ function parse_test(file) {
|
||||
}));
|
||||
}
|
||||
|
||||
function read_boolean(stat) {
|
||||
if (stat.TYPE == "SimpleStatement") {
|
||||
var body = stat.body;
|
||||
if (body instanceof U.AST_Boolean) {
|
||||
return body.value;
|
||||
}
|
||||
}
|
||||
throw new Error("Should be boolean");
|
||||
}
|
||||
|
||||
function read_string(stat) {
|
||||
if (stat.TYPE == "SimpleStatement") {
|
||||
var body = stat.body;
|
||||
@@ -279,7 +292,11 @@ function parse_test(file) {
|
||||
}
|
||||
|
||||
function get_one_test(name, block) {
|
||||
var test = { name: name, options: {} };
|
||||
var test = {
|
||||
name: name,
|
||||
options: {},
|
||||
reminify: true,
|
||||
};
|
||||
var tw = new U.TreeWalker(function(node, descend){
|
||||
if (node instanceof U.AST_Assign) {
|
||||
if (!(node.left instanceof U.AST_SymbolRef)) {
|
||||
@@ -299,6 +316,7 @@ function parse_test(file) {
|
||||
"expect_warnings",
|
||||
"expect_stdout",
|
||||
"node_version",
|
||||
"reminify",
|
||||
].indexOf(label.name) >= 0,
|
||||
tmpl("Unsupported label {name} [{line},{col}]", {
|
||||
name: label.name,
|
||||
@@ -309,6 +327,9 @@ function parse_test(file) {
|
||||
var stat = node.body;
|
||||
if (label.name == "expect_exact" || label.name == "node_version") {
|
||||
test[label.name] = read_string(stat);
|
||||
} else if (label.name == "reminify") {
|
||||
var value = read_boolean(stat);
|
||||
test.reminify = value == null || value;
|
||||
} else if (label.name == "expect_stdout") {
|
||||
var body = stat.body;
|
||||
if (body instanceof U.AST_Boolean) {
|
||||
@@ -358,14 +379,17 @@ function evaluate(code) {
|
||||
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];
|
||||
}
|
||||
});
|
||||
options.keep_fnames = orig_options.keep_fnames;
|
||||
options.keep_classnames = orig_options.keep_classnames;
|
||||
if (orig_options.compress) {
|
||||
options.compress.keep_classnames = orig_options.compress.keep_classnames;
|
||||
options.compress.keep_fargs = orig_options.compress.keep_fargs;
|
||||
options.compress.keep_fnames = orig_options.compress.keep_fnames;
|
||||
}
|
||||
if (orig_options.mangle) {
|
||||
options.mangle.keep_classnames = orig_options.mangle.keep_classnames;
|
||||
options.mangle.keep_fnames = orig_options.mangle.keep_fnames;
|
||||
}
|
||||
var options_formatted = JSON.stringify(options, null, 4);
|
||||
var result = U.minify(input_code, options);
|
||||
if (result.error) {
|
||||
|
||||
@@ -17,24 +17,30 @@ function safe_log(arg, level) {
|
||||
return arg;
|
||||
}
|
||||
|
||||
function strip_func_ids(text) {
|
||||
return text.toString().replace(/F[0-9]{6}N/g, "<F<>N>");
|
||||
}
|
||||
|
||||
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() {",
|
||||
" var id = 100000;",
|
||||
" return function() {",
|
||||
' if (this === Array) return "[Function: Array]";',
|
||||
' if (this === Object) return "[Function: Object]";',
|
||||
" var i = this.name;",
|
||||
' if (typeof i != "number") {',
|
||||
" i = ++id;",
|
||||
" var n = this.name;",
|
||||
' if (!/^F[0-9]{6}N$/.test(n)) {',
|
||||
' n = "F" + ++id + "N";',
|
||||
].concat(Object.getOwnPropertyDescriptor(Function.prototype, "name").configurable ? [
|
||||
' Object.defineProperty(this, "name", {',
|
||||
" get: function() {",
|
||||
" return i;",
|
||||
" return n;",
|
||||
" }",
|
||||
" });",
|
||||
] : [], [
|
||||
" }",
|
||||
' return "[Function: " + i + "]";',
|
||||
' return "[Function: " + n + "]";',
|
||||
" }",
|
||||
"}();",
|
||||
'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);
|
||||
actual = actual.message.slice(actual.message.lastIndexOf("\n") + 1);
|
||||
}
|
||||
return expected == actual;
|
||||
return strip_func_ids(expected) == strip_func_ids(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);
|
||||
}
|
||||
}
|
||||
@@ -998,10 +998,11 @@ function log_suspects(minify_options, component) {
|
||||
if (typeof options != "object") options = {};
|
||||
var defs = default_options[component];
|
||||
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 o = JSON.parse(JSON.stringify(options));
|
||||
o[name] = false;
|
||||
o[name] = flip;
|
||||
m[component] = o;
|
||||
var result = UglifyJS.minify(original_code, m);
|
||||
if (result.error) {
|
||||
@@ -1022,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) {
|
||||
if (!ok) errorln('\n\n\n\n\n\n!!!!!!!!!!\n\n\n');
|
||||
errorln("//=============================================================");
|
||||
@@ -1056,6 +1074,7 @@ function log(options) {
|
||||
errorln();
|
||||
if (!ok && typeof uglify_code == "string") {
|
||||
Object.keys(default_options).forEach(log_suspects.bind(null, options));
|
||||
log_rename(options);
|
||||
errorln("!!!!!! Failed... round " + round);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
"output": {
|
||||
"beautify": true,
|
||||
"bracketize": true
|
||||
}
|
||||
},
|
||||
"rename": true
|
||||
},
|
||||
{
|
||||
"compress": false
|
||||
@@ -20,7 +21,13 @@
|
||||
{
|
||||
"compress": {
|
||||
"keep_fargs": false,
|
||||
"passes": 100
|
||||
"passes": 1e6,
|
||||
"sequences": 1e6,
|
||||
"unsafe": true,
|
||||
"unsafe_Function": true,
|
||||
"unsafe_math": true,
|
||||
"unsafe_proto": true,
|
||||
"unsafe_regexp": true
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user