Compare commits
61 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aa2a9fbedb | ||
|
|
3596b4feda | ||
|
|
51deeff72e | ||
|
|
4c227cc6bd | ||
|
|
2426657daa | ||
|
|
e1b03d0235 | ||
|
|
f1b3e9df1e | ||
|
|
fcc87edb71 | ||
|
|
8b464331ba | ||
|
|
9f57920566 | ||
|
|
933ca9ddd8 | ||
|
|
74e36e4456 | ||
|
|
4382bfe848 | ||
|
|
b6f250f5c9 | ||
|
|
5d69545299 | ||
|
|
139fad0c05 | ||
|
|
99946a3993 | ||
|
|
053cb27fe3 | ||
|
|
25017978e7 | ||
|
|
f749863cb2 | ||
|
|
123f9cf987 | ||
|
|
a758b40e3f | ||
|
|
44e5e99aae | ||
|
|
be53c4838b | ||
|
|
0c7b016fa7 | ||
|
|
00665766da | ||
|
|
88b4283200 | ||
|
|
d2bd0d1c1c | ||
|
|
25441d44f6 | ||
|
|
a025392a30 | ||
|
|
ad5f5ef2a3 | ||
|
|
40e669eacb | ||
|
|
ad3a331ca3 | ||
|
|
3c9e1693d5 | ||
|
|
8bc03dc6c4 | ||
|
|
2152f00de2 | ||
|
|
94aae05d45 | ||
|
|
0dbf2b1d3c | ||
|
|
59b23b8c13 | ||
|
|
5979b195fe | ||
|
|
a1cff23377 | ||
|
|
c82fc1ef71 | ||
|
|
740f93f5a9 | ||
|
|
d4caa97b88 | ||
|
|
c2ca7b7659 | ||
|
|
59edda6ca5 | ||
|
|
1668bc33c3 | ||
|
|
01f1e3fef8 | ||
|
|
27aa85f84b | ||
|
|
33c9c48318 | ||
|
|
63f16e4616 | ||
|
|
cb6dd34b98 | ||
|
|
27727e6926 | ||
|
|
a968ddc78c | ||
|
|
f70462aeb2 | ||
|
|
3aa92c76cc | ||
|
|
fc6a66836a | ||
|
|
31167da1a9 | ||
|
|
7db2ada880 | ||
|
|
e31bbe329a | ||
|
|
8946c87011 |
6
.github/workflows/ufuzz.yml
vendored
6
.github/workflows/ufuzz.yml
vendored
@@ -17,13 +17,13 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- node: latest
|
||||
- node: '16'
|
||||
os: macos-latest
|
||||
- node: '8'
|
||||
- node: '12'
|
||||
os: ubuntu-latest
|
||||
- node: '8'
|
||||
os: ubuntu-latest
|
||||
- node: '8'
|
||||
- node: '12'
|
||||
os: windows-latest
|
||||
- node: '8'
|
||||
os: windows-latest
|
||||
|
||||
67
README.md
67
README.md
@@ -118,6 +118,7 @@ a double dash to prevent input files being used as option arguments:
|
||||
--keep-fargs Do not mangle/drop function arguments.
|
||||
--keep-fnames Do not mangle/drop function names. Useful for
|
||||
code relying on Function.prototype.name.
|
||||
--module Process input as ES module (implies --toplevel)
|
||||
--name-cache <file> File to hold mangled name mappings.
|
||||
--self Build UglifyJS as a library (implies --wrap UglifyJS)
|
||||
--source-map [options] Enable source map/specify source map options:
|
||||
@@ -146,7 +147,7 @@ a double dash to prevent input files being used as option arguments:
|
||||
--warn Print warning messages.
|
||||
--webkit Support non-standard Safari/Webkit.
|
||||
Equivalent to setting `webkit: true` in `minify()`
|
||||
for `mangle` and `output` options.
|
||||
for `compress`, `mangle` and `output` options.
|
||||
By default UglifyJS will not try to be Safari-proof.
|
||||
--wrap <name> Embed everything in a big function, making the
|
||||
“exports” and “global” variables available. You
|
||||
@@ -517,6 +518,10 @@ if (result.error) throw result.error;
|
||||
- `mangle.properties` (default: `false`) — a subcategory of the mangle option.
|
||||
Pass an object to specify custom [mangle property options](#mangle-properties-options).
|
||||
|
||||
- `module` (default: `false`) — set to `true` if you wish to process input as
|
||||
ES module, i.e. implicit `"use strict";` and support for top-level `await`,
|
||||
alongside with `toplevel` enabled.
|
||||
|
||||
- `nameCache` (default: `null`) — pass an empty object `{}` or a previously
|
||||
used `nameCache` object if you wish to cache mangled variable and
|
||||
property names across multiple invocations of `minify()`. Note: this is
|
||||
@@ -628,7 +633,13 @@ to be `false` and all symbol names will be omitted.
|
||||
|
||||
- `bare_returns` (default: `false`) — support top level `return` statements
|
||||
|
||||
- `html5_comments` (default: `true`)
|
||||
- `expression` (default: `false`) — parse as a single expression, e.g. JSON
|
||||
|
||||
- `html5_comments` (default: `true`) — process HTML comment as workaround for
|
||||
browsers which do not recognise `<script>` tags
|
||||
|
||||
- `module` (default: `false`) — set to `true` if you wish to process input as
|
||||
ES module, i.e. implicit `"use strict";` and support for top-level `await`.
|
||||
|
||||
- `shebang` (default: `true`) — support `#!command` as the first line
|
||||
|
||||
@@ -728,6 +739,9 @@ to be `false` and all symbol names will be omitted.
|
||||
|
||||
- `merge_vars` (default: `true`) — combine and reuse variables.
|
||||
|
||||
- `module` (default: `false`) — set to `true` if you wish to process input as
|
||||
ES module, i.e. implicit `"use strict";` alongside with `toplevel` enabled.
|
||||
|
||||
- `negate_iife` (default: `true`) — negate "Immediately-Called Function Expressions"
|
||||
where the return value is discarded, to avoid the parens that the
|
||||
code generator would insert.
|
||||
@@ -804,8 +818,9 @@ to be `false` and all symbol names will be omitted.
|
||||
|
||||
- `unsafe` (default: `false`) — apply "unsafe" transformations (discussion below)
|
||||
|
||||
- `unsafe_comps` (default: `false`) — compress expressions like `a <= b` assuming
|
||||
none of the operands can be (coerced to) `NaN`.
|
||||
- `unsafe_comps` (default: `false`) — assume operands cannot be (coerced to) `NaN`
|
||||
in numeric comparisons, e.g. `a <= b`. In addition, expressions involving `in`
|
||||
or `instanceof` would never throw.
|
||||
|
||||
- `unsafe_Function` (default: `false`) — compress and mangle `Function(args, code)`
|
||||
when both `args` and `code` are string literals.
|
||||
@@ -1331,10 +1346,8 @@ To allow for better optimizations, the compiler makes various assumptions:
|
||||
- Later versions of JavaScript will throw `SyntaxError` with the following:
|
||||
```javascript
|
||||
var await;
|
||||
async function f() {
|
||||
class A {
|
||||
static p = await;
|
||||
}
|
||||
class A {
|
||||
static p = await;
|
||||
}
|
||||
// SyntaxError: Unexpected reserved word
|
||||
```
|
||||
@@ -1389,3 +1402,41 @@ To allow for better optimizations, the compiler makes various assumptions:
|
||||
// Actual: "FAIL"
|
||||
```
|
||||
UglifyJS may modify the input which in turn may suppress those errors.
|
||||
- Some versions of Chrome and Node.js will give incorrect results with the
|
||||
following:
|
||||
```javascript
|
||||
(async function(a) {
|
||||
(function() {
|
||||
var b = await => console.log("PASS");
|
||||
b();
|
||||
})();
|
||||
})().catch(console.error);
|
||||
// Expected: "PASS"
|
||||
// Actual: SyntaxError: Unexpected reserved word
|
||||
```
|
||||
UglifyJS may modify the input which in turn may suppress those errors.
|
||||
- Later versions of Chrome and Node.js will give incorrect results with the
|
||||
following:
|
||||
```javascript
|
||||
try {
|
||||
f();
|
||||
function f() {
|
||||
throw 42;
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(typeof f, e);
|
||||
}
|
||||
// Expected: "function 42"
|
||||
// Actual: "undefined 42"
|
||||
```
|
||||
UglifyJS may modify the input which in turn may suppress those errors.
|
||||
- Later versions of JavaScript will throw `SyntaxError` with the following:
|
||||
```javascript
|
||||
"use strict";
|
||||
console.log(function f() {
|
||||
return f = "PASS";
|
||||
}());
|
||||
// Expected: "PASS"
|
||||
// Actual: TypeError: invalid assignment to const 'f'
|
||||
```
|
||||
UglifyJS may modify the input which in turn may suppress those errors.
|
||||
|
||||
@@ -107,6 +107,7 @@ function process_option(name, no_value) {
|
||||
" --ie Support non-standard Internet Explorer.",
|
||||
" --keep-fargs Do not mangle/drop function arguments.",
|
||||
" --keep-fnames Do not mangle/drop function names. Useful for code relying on Function.prototype.name.",
|
||||
" --module Process input as ES module (implies --toplevel)",
|
||||
" --name-cache <file> File to hold mangled name mappings.",
|
||||
" --rename Force symbol expansion.",
|
||||
" --no-rename Disable symbol expansion.",
|
||||
@@ -152,6 +153,7 @@ function process_option(name, no_value) {
|
||||
case "annotations":
|
||||
case "ie":
|
||||
case "ie8":
|
||||
case "module":
|
||||
case "timings":
|
||||
case "toplevel":
|
||||
case "v8":
|
||||
|
||||
44
lib/ast.js
44
lib/ast.js
@@ -534,7 +534,7 @@ var AST_With = DEFNODE("With", "expression", {
|
||||
/* -----[ scope and functions ]----- */
|
||||
|
||||
var AST_Scope = DEFNODE("Scope", "fn_defs may_call_this uses_eval uses_with", {
|
||||
$documentation: "Base class for all statements introducing a lexical scope",
|
||||
$documentation: "Base class for all statements introducing a lambda scope",
|
||||
$propdoc: {
|
||||
uses_eval: "[boolean/S] tells whether this scope contains a direct call to the global `eval`",
|
||||
uses_with: "[boolean/S] tells whether this scope uses the `with` statement",
|
||||
@@ -592,6 +592,10 @@ var AST_Toplevel = DEFNODE("Toplevel", "globals", {
|
||||
}
|
||||
}, AST_Scope);
|
||||
|
||||
var AST_ClassInitBlock = DEFNODE("ClassInitBlock", null, {
|
||||
$documentation: "Value for `class` static initialization blocks",
|
||||
}, AST_Scope);
|
||||
|
||||
var AST_Lambda = DEFNODE("Lambda", "argnames length_read rest safe_ids uses_arguments", {
|
||||
$documentation: "Base class for functions",
|
||||
$propdoc: {
|
||||
@@ -827,6 +831,9 @@ var AST_Class = DEFNODE("Class", "extends name properties", {
|
||||
extends: "[AST_Node?] the super class, or null if not specified",
|
||||
properties: "[AST_ClassProperty*] array of class properties",
|
||||
},
|
||||
resolve: function(def_class) {
|
||||
return def_class ? this : this.parent_scope.resolve();
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -851,9 +858,6 @@ var AST_DefClass = DEFNODE("DefClass", null, {
|
||||
$propdoc: {
|
||||
name: "[AST_SymbolDefClass] the name of this class",
|
||||
},
|
||||
resolve: function(def_class) {
|
||||
return def_class ? this : this.parent_scope.resolve();
|
||||
},
|
||||
_validate: function() {
|
||||
if (!(this.name instanceof AST_SymbolDefClass)) throw new Error("name must be AST_SymbolDefClass");
|
||||
},
|
||||
@@ -874,7 +878,7 @@ var AST_ClassExpression = DEFNODE("ClassExpression", null, {
|
||||
var AST_ClassProperty = DEFNODE("ClassProperty", "key private static value", {
|
||||
$documentation: "Base class for `class` properties",
|
||||
$propdoc: {
|
||||
key: "[string|AST_Node] property name (AST_Node for computed property)",
|
||||
key: "[string|AST_Node?] property name (AST_Node for computed property, null for initialization block)",
|
||||
private: "[boolean] whether this is a private property",
|
||||
static: "[boolean] whether this is a static property",
|
||||
value: "[AST_Node?] property value (AST_Accessor for getters/setters, AST_LambdaExpression for methods, null if not specified for fields)",
|
||||
@@ -888,7 +892,9 @@ var AST_ClassProperty = DEFNODE("ClassProperty", "key private static value", {
|
||||
},
|
||||
_validate: function() {
|
||||
if (this.TYPE == "ClassProperty") throw new Error("should not instantiate AST_ClassProperty");
|
||||
if (typeof this.key != "string") {
|
||||
if (this instanceof AST_ClassInit) {
|
||||
if (this.key != null) throw new Error("key must be null");
|
||||
} else if (typeof this.key != "string") {
|
||||
if (!(this.key instanceof AST_Node)) throw new Error("key must be string or AST_Node");
|
||||
must_be_expression(this, "key");
|
||||
}
|
||||
@@ -928,6 +934,17 @@ var AST_ClassMethod = DEFNODE("ClassMethod", null, {
|
||||
},
|
||||
}, AST_ClassProperty);
|
||||
|
||||
var AST_ClassInit = DEFNODE("ClassInit", null, {
|
||||
$documentation: "A `class` static initialization block",
|
||||
_validate: function() {
|
||||
if (!this.static) throw new Error("static must be true");
|
||||
if (!(this.value instanceof AST_ClassInitBlock)) throw new Error("value must be AST_ClassInitBlock");
|
||||
},
|
||||
initialize: function() {
|
||||
this.static = true;
|
||||
},
|
||||
}, AST_ClassProperty);
|
||||
|
||||
/* -----[ JUMPS ]----- */
|
||||
|
||||
var AST_Jump = DEFNODE("Jump", null, {
|
||||
@@ -1837,7 +1854,7 @@ var AST_Label = DEFNODE("Label", "references", {
|
||||
initialize: function() {
|
||||
this.references = [];
|
||||
this.thedef = this;
|
||||
}
|
||||
},
|
||||
}, AST_Symbol);
|
||||
|
||||
var AST_SymbolRef = DEFNODE("SymbolRef", "fixed in_arg redef", {
|
||||
@@ -2039,16 +2056,21 @@ TreeWalker.prototype = {
|
||||
return this.stack[this.stack.length - 2 - (n || 0)];
|
||||
},
|
||||
push: function(node) {
|
||||
if (node instanceof AST_Lambda) {
|
||||
var value;
|
||||
if (node instanceof AST_Class) {
|
||||
this.directives = Object.create(this.directives);
|
||||
value = "use strict";
|
||||
} else if (node instanceof AST_Directive) {
|
||||
value = node.value;
|
||||
} else if (node instanceof AST_Lambda) {
|
||||
this.directives = Object.create(this.directives);
|
||||
} else if (node instanceof AST_Directive && !this.directives[node.value]) {
|
||||
this.directives[node.value] = node;
|
||||
}
|
||||
if (value && !this.directives[value]) this.directives[value] = node;
|
||||
this.stack.push(node);
|
||||
},
|
||||
pop: function() {
|
||||
var node = this.stack.pop();
|
||||
if (node instanceof AST_Lambda) {
|
||||
if (node instanceof AST_Class || node instanceof AST_Lambda) {
|
||||
this.directives = Object.getPrototypeOf(this.directives);
|
||||
}
|
||||
},
|
||||
|
||||
780
lib/compress.js
780
lib/compress.js
File diff suppressed because it is too large
Load Diff
@@ -81,13 +81,14 @@ function minify(files, options) {
|
||||
keep_fargs: false,
|
||||
keep_fnames: false,
|
||||
mangle: {},
|
||||
module: false,
|
||||
nameCache: null,
|
||||
output: {},
|
||||
parse: {},
|
||||
rename: undefined,
|
||||
sourceMap: false,
|
||||
timings: false,
|
||||
toplevel: false,
|
||||
toplevel: !!(options && options["module"]),
|
||||
v8: false,
|
||||
validate: false,
|
||||
warnings: false,
|
||||
@@ -101,6 +102,7 @@ function minify(files, options) {
|
||||
if (options.ie) set_shorthand("ie", options, [ "compress", "mangle", "output", "rename" ]);
|
||||
if (options.keep_fargs) set_shorthand("keep_fargs", options, [ "compress", "mangle", "rename" ]);
|
||||
if (options.keep_fnames) set_shorthand("keep_fnames", options, [ "compress", "mangle", "rename" ]);
|
||||
if (options.module) set_shorthand("module", options, [ "compress", "parse" ]);
|
||||
if (options.toplevel) set_shorthand("toplevel", options, [ "compress", "mangle", "rename" ]);
|
||||
if (options.v8) set_shorthand("v8", options, [ "mangle", "output", "rename" ]);
|
||||
if (options.webkit) set_shorthand("webkit", options, [ "compress", "mangle", "output", "rename" ]);
|
||||
|
||||
@@ -260,6 +260,15 @@ function OutputStream(options) {
|
||||
|
||||
var require_semicolon = makePredicate("( [ + * / - , .");
|
||||
|
||||
function require_space(prev, ch, str) {
|
||||
return is_identifier_char(prev) && (is_identifier_char(ch) || ch == "\\")
|
||||
|| (ch == "/" && ch == prev)
|
||||
|| ((ch == "+" || ch == "-") && ch == last)
|
||||
|| last == "--" && ch == ">"
|
||||
|| last == "!" && str == "--"
|
||||
|| prev == "/" && (str == "in" || str == "instanceof");
|
||||
}
|
||||
|
||||
var print = options.beautify
|
||||
|| options.comments
|
||||
|| options.max_line_len
|
||||
@@ -312,12 +321,7 @@ function OutputStream(options) {
|
||||
}
|
||||
|
||||
if (might_need_space) {
|
||||
if (is_identifier_char(prev) && (is_identifier_char(ch) || ch == "\\")
|
||||
|| (ch == "/" && ch == prev)
|
||||
|| ((ch == "+" || ch == "-") && ch == last)
|
||||
|| str == "--" && last == "!"
|
||||
|| str == "in" && prev == "/"
|
||||
|| last == "--" && ch == ">") {
|
||||
if (require_space(prev, ch, str)) {
|
||||
output += " ";
|
||||
current_col++;
|
||||
}
|
||||
@@ -355,14 +359,7 @@ function OutputStream(options) {
|
||||
}
|
||||
}
|
||||
if (might_need_space) {
|
||||
if (is_identifier_char(prev) && (is_identifier_char(ch) || ch == "\\")
|
||||
|| (ch == "/" && ch == prev)
|
||||
|| ((ch == "+" || ch == "-") && ch == last)
|
||||
|| str == "--" && last == "!"
|
||||
|| str == "in" && prev == "/"
|
||||
|| last == "--" && ch == ">") {
|
||||
output += " ";
|
||||
}
|
||||
if (require_space(prev, ch, str)) output += " ";
|
||||
if (prev != "<" || str != "!") might_need_space = false;
|
||||
}
|
||||
output += str;
|
||||
@@ -1257,6 +1254,11 @@ function OutputStream(options) {
|
||||
}
|
||||
print_method(self, output);
|
||||
});
|
||||
DEFPRINT(AST_ClassInit, function(output) {
|
||||
output.print("static");
|
||||
output.space();
|
||||
print_braced(this.value, output);
|
||||
});
|
||||
|
||||
/* -----[ jumps ]----- */
|
||||
function print_jump(kind, prop) {
|
||||
@@ -1814,9 +1816,6 @@ function OutputStream(options) {
|
||||
case "\u2029": return "\\u2029";
|
||||
}
|
||||
}));
|
||||
var p = output.parent();
|
||||
if (p instanceof AST_Binary && /^in/.test(p.operator) && p.left === this)
|
||||
output.print(" ");
|
||||
});
|
||||
|
||||
function force_statement(stat, output) {
|
||||
|
||||
37
lib/parse.js
37
lib/parse.js
@@ -237,8 +237,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
newline_before : false,
|
||||
regex_allowed : false,
|
||||
comments_before : [],
|
||||
directives : {},
|
||||
directive_stack : [],
|
||||
directives : Object.create(null),
|
||||
read_template : with_eof_error("Unterminated template literal", function(strings) {
|
||||
var s = "";
|
||||
for (;;) {
|
||||
@@ -635,24 +634,19 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
};
|
||||
|
||||
next_token.add_directive = function(directive) {
|
||||
S.directive_stack[S.directive_stack.length - 1].push(directive);
|
||||
if (S.directives[directive]) S.directives[directive]++;
|
||||
else S.directives[directive] = 1;
|
||||
S.directives[directive] = true;
|
||||
}
|
||||
|
||||
next_token.push_directives_stack = function() {
|
||||
S.directive_stack.push([]);
|
||||
S.directives = Object.create(S.directives);
|
||||
}
|
||||
|
||||
next_token.pop_directives_stack = function() {
|
||||
var directives = S.directive_stack.pop();
|
||||
for (var i = directives.length; --i >= 0;) {
|
||||
S.directives[directives[i]]--;
|
||||
}
|
||||
S.directives = Object.getPrototypeOf(S.directives);
|
||||
}
|
||||
|
||||
next_token.has_directive = function(directive) {
|
||||
return S.directives[directive] > 0;
|
||||
return !!S.directives[directive];
|
||||
}
|
||||
|
||||
return next_token;
|
||||
@@ -699,6 +693,7 @@ function parse($TEXT, options) {
|
||||
expression : false,
|
||||
filename : null,
|
||||
html5_comments : true,
|
||||
module : false,
|
||||
shebang : true,
|
||||
strict : false,
|
||||
toplevel : null,
|
||||
@@ -1124,6 +1119,18 @@ function parse($TEXT, options) {
|
||||
}));
|
||||
continue;
|
||||
}
|
||||
if (fixed && is("punc", "{")) {
|
||||
props.push(new AST_ClassInit({
|
||||
start: start,
|
||||
value: new AST_ClassInitBlock({
|
||||
start: start,
|
||||
body: block_(),
|
||||
end: prev(),
|
||||
}),
|
||||
end: prev(),
|
||||
}));
|
||||
continue;
|
||||
}
|
||||
var internal = is("name") && /^#/.test(S.token.value);
|
||||
var key = as_property_key();
|
||||
if (is("punc", "(")) {
|
||||
@@ -1340,11 +1347,11 @@ function parse($TEXT, options) {
|
||||
var loop = S.in_loop;
|
||||
var labels = S.labels;
|
||||
++S.in_function;
|
||||
S.in_directives = true;
|
||||
S.input.push_directives_stack();
|
||||
S.in_loop = 0;
|
||||
S.labels = [];
|
||||
if (is("punc", "{")) {
|
||||
S.in_directives = true;
|
||||
body = block_();
|
||||
value = null;
|
||||
} else {
|
||||
@@ -1412,7 +1419,7 @@ function parse($TEXT, options) {
|
||||
name: name,
|
||||
argnames: argnames,
|
||||
rest: argnames.rest || null,
|
||||
body: body
|
||||
body: body,
|
||||
});
|
||||
if (is_strict) {
|
||||
if (name) strict_verify_symbol(name);
|
||||
@@ -2550,6 +2557,10 @@ function parse($TEXT, options) {
|
||||
return function() {
|
||||
var start = S.token;
|
||||
var body = [];
|
||||
if (options.module) {
|
||||
S.in_async = true;
|
||||
S.input.add_directive("use strict");
|
||||
}
|
||||
S.input.push_directives_stack();
|
||||
while (!is("eof"))
|
||||
body.push(statement());
|
||||
|
||||
24
lib/scope.js
24
lib/scope.js
@@ -64,19 +64,20 @@ SymbolDef.prototype = {
|
||||
this.references.forEach(fn);
|
||||
},
|
||||
mangle: function(options) {
|
||||
var cache = options.cache && options.cache.props;
|
||||
if (this.global && cache && cache.has(this.name)) {
|
||||
if (this.mangled_name) return;
|
||||
var cache = this.global && options.cache && options.cache.props;
|
||||
if (cache && cache.has(this.name)) {
|
||||
this.mangled_name = cache.get(this.name);
|
||||
} else if (!this.mangled_name && !this.unmangleable(options)) {
|
||||
} else if (this.unmangleable(options)) {
|
||||
names_in_use(this.scope, options).set(this.name, true);
|
||||
} else {
|
||||
var def = this.redefined();
|
||||
if (def) {
|
||||
this.mangled_name = def.mangled_name || def.name;
|
||||
} else {
|
||||
this.mangled_name = next_mangled_name(this, options);
|
||||
}
|
||||
if (this.global && cache) {
|
||||
cache.set(this.name, this.mangled_name);
|
||||
}
|
||||
if (cache) cache.set(this.name, this.mangled_name);
|
||||
}
|
||||
},
|
||||
redefined: function() {
|
||||
@@ -621,14 +622,10 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
|
||||
var lname = -1;
|
||||
var redefined = [];
|
||||
var tw = new TreeWalker(function(node, descend) {
|
||||
if (node instanceof AST_LabeledStatement) {
|
||||
// `lname` is incremented when we get to the `AST_Label`
|
||||
var save_nesting = lname;
|
||||
descend();
|
||||
if (!options.v8 || !in_label(tw)) lname = save_nesting;
|
||||
return true;
|
||||
}
|
||||
var save_nesting;
|
||||
if (node instanceof AST_BlockScope) {
|
||||
// `lname` is incremented when we get to the `AST_Label`
|
||||
if (node instanceof AST_LabeledStatement) save_nesting = lname;
|
||||
if (options.webkit && node instanceof AST_IterationStatement && node.init instanceof AST_Let) {
|
||||
node.init.definitions.forEach(function(defn) {
|
||||
defn.name.match_symbol(function(sym) {
|
||||
@@ -674,6 +671,7 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
|
||||
}));
|
||||
}
|
||||
to_mangle.forEach(mangle);
|
||||
if (node instanceof AST_LabeledStatement && !(options.v8 && in_label(tw))) lname = save_nesting;
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_Label) {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||
"license": "BSD-2-Clause",
|
||||
"version": "3.15.5",
|
||||
"version": "3.16.2",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
},
|
||||
|
||||
@@ -69,9 +69,7 @@ function make_code(ast, options) {
|
||||
function parse_test(file) {
|
||||
var script = fs.readFileSync(file, "utf8");
|
||||
try {
|
||||
var ast = U.parse(script, {
|
||||
filename: file
|
||||
});
|
||||
var ast = U.parse(script, { filename: file });
|
||||
} catch (e) {
|
||||
console.error("Caught error while parsing tests in " + file);
|
||||
console.error(e);
|
||||
@@ -98,14 +96,14 @@ function parse_test(file) {
|
||||
file: file,
|
||||
line: node.start.line,
|
||||
col: node.start.col,
|
||||
code: make_code(node, { beautify: false })
|
||||
code: make_code(node, { beautify: false }),
|
||||
}));
|
||||
}
|
||||
|
||||
function read_string(stat) {
|
||||
if (stat.TYPE == "SimpleStatement") {
|
||||
var body = stat.body;
|
||||
switch(body.TYPE) {
|
||||
switch (body.TYPE) {
|
||||
case "String":
|
||||
return body.value;
|
||||
case "Array":
|
||||
@@ -142,7 +140,7 @@ function parse_test(file) {
|
||||
].indexOf(label.name) >= 0, tmpl("Unsupported label {name} [{line},{col}]", {
|
||||
name: label.name,
|
||||
line: label.start.line,
|
||||
col: label.start.col
|
||||
col: label.start.col,
|
||||
}));
|
||||
var stat = node.body;
|
||||
if (label.name == "expect_exact" || label.name == "node_version") {
|
||||
@@ -155,12 +153,12 @@ function parse_test(file) {
|
||||
var ctor = global[body.expression.name];
|
||||
assert.ok(ctor === Error || ctor.prototype instanceof Error, tmpl("Unsupported expect_stdout format [{line},{col}]", {
|
||||
line: label.start.line,
|
||||
col: label.start.col
|
||||
col: label.start.col,
|
||||
}));
|
||||
test[label.name] = ctor.apply(null, body.args.map(function(node) {
|
||||
assert.ok(node instanceof U.AST_Constant, tmpl("Unsupported expect_stdout format [{line},{col}]", {
|
||||
line: label.start.line,
|
||||
col: label.start.col
|
||||
col: label.start.col,
|
||||
}));
|
||||
return node.value;
|
||||
}));
|
||||
|
||||
@@ -1106,3 +1106,17 @@ issue_5416: {
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5495: {
|
||||
input: {
|
||||
console.log((() => {
|
||||
"use strict";
|
||||
return function() {
|
||||
return this;
|
||||
}();
|
||||
})());
|
||||
}
|
||||
expect_exact: 'console.log((()=>{"use strict";return function(){return this}()})());'
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
@@ -1293,6 +1293,21 @@ functions_inner_var: {
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
instanceof_lambda: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
console.log(42 instanceof async function() {});
|
||||
}
|
||||
expect: {
|
||||
console.log(false);
|
||||
}
|
||||
expect_stdout: "false"
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_4335_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
@@ -1748,8 +1763,8 @@ issue_4454_2: {
|
||||
expect: {
|
||||
function f(a) {
|
||||
(async function(c = console.log(a)) {})();
|
||||
var a = 42..toString();
|
||||
console.log(a);
|
||||
var b = 42..toString();
|
||||
console.log(b);
|
||||
}
|
||||
f("PASS");
|
||||
}
|
||||
@@ -2427,80 +2442,6 @@ issue_5023_2: {
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5032_normal: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
webkit: false,
|
||||
}
|
||||
input: {
|
||||
function log(value) {
|
||||
console.log(value);
|
||||
return value;
|
||||
}
|
||||
async function f(a) {
|
||||
var b = log(a), c = b;
|
||||
log(b);
|
||||
log(c);
|
||||
}
|
||||
f("PASS");
|
||||
}
|
||||
expect: {
|
||||
function log(value) {
|
||||
console.log(value);
|
||||
return value;
|
||||
}
|
||||
async function f(a) {
|
||||
var a = log(a), c = a;
|
||||
log(a);
|
||||
log(c);
|
||||
}
|
||||
f("PASS");
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5032_webkit: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
webkit: true,
|
||||
}
|
||||
input: {
|
||||
function log(value) {
|
||||
console.log(value);
|
||||
return value;
|
||||
}
|
||||
async function f(a) {
|
||||
var b = log(a), c = b;
|
||||
log(b);
|
||||
log(c);
|
||||
}
|
||||
f("PASS");
|
||||
}
|
||||
expect: {
|
||||
function log(value) {
|
||||
console.log(value);
|
||||
return value;
|
||||
}
|
||||
async function f(a) {
|
||||
var b = log(a), c = b;
|
||||
log(b);
|
||||
log(c);
|
||||
}
|
||||
f("PASS");
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5034: {
|
||||
options = {
|
||||
functions: true,
|
||||
@@ -2959,3 +2900,278 @@ issue_5305_3: {
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5456: {
|
||||
options = {
|
||||
inline: true,
|
||||
merge_vars: true,
|
||||
}
|
||||
input: {
|
||||
var a = true;
|
||||
(function() {
|
||||
(function(b, c) {
|
||||
var d = async function() {
|
||||
c = await null;
|
||||
}();
|
||||
var e = function() {
|
||||
if (c)
|
||||
console.log(typeof d);
|
||||
while (b);
|
||||
}();
|
||||
})(function(i) {
|
||||
return console.log("foo") && i;
|
||||
}(a));
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
var a = true;
|
||||
(function() {
|
||||
b = (i = a, console.log("foo") && i),
|
||||
d = async function() {
|
||||
c = await null;
|
||||
}(),
|
||||
e = function() {
|
||||
if (c) console.log(typeof d);
|
||||
while (b);
|
||||
}(),
|
||||
void 0;
|
||||
var b, c, d, e;
|
||||
var i;
|
||||
})();
|
||||
}
|
||||
expect_stdout: "foo"
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5478: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
A = {
|
||||
get then() {
|
||||
a = "FAIL";
|
||||
},
|
||||
};
|
||||
var a = "PASS";
|
||||
(async function() {
|
||||
for (var b in "foo")
|
||||
return void A;
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
A = {
|
||||
get then() {
|
||||
a = "FAIL";
|
||||
},
|
||||
};
|
||||
var a = "PASS";
|
||||
(async function() {
|
||||
for (var b in "foo")
|
||||
return !A;
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5493: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
(async function(a) {
|
||||
var b = await [ 42 || b, a = b ];
|
||||
console.log(a);
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(async function(a) {
|
||||
var b = await [ 42 || b, a = b ];
|
||||
console.log(a);
|
||||
})();
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5506: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
(async function() {
|
||||
a = null in (a = "PASS");
|
||||
})();
|
||||
return a;
|
||||
}("FAIL"));
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a) {
|
||||
(async function() {
|
||||
a = null in (a = "PASS");
|
||||
})();
|
||||
return a;
|
||||
}("FAIL"));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5528_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(async function() {
|
||||
await function() {
|
||||
try {
|
||||
return;
|
||||
} finally {
|
||||
console.log("foo");
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log("bar");
|
||||
}
|
||||
expect: {
|
||||
(async function() {
|
||||
await function() {
|
||||
try {
|
||||
return;
|
||||
} finally {
|
||||
console.log("foo");
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log("bar");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5528_2: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(async function() {
|
||||
await function() {
|
||||
try {
|
||||
return 42;
|
||||
} finally {
|
||||
console.log("foo");
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log("bar");
|
||||
}
|
||||
expect: {
|
||||
(async function() {
|
||||
await function() {
|
||||
try {
|
||||
return 42;
|
||||
} finally {
|
||||
console.log("foo");
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log("bar");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5528_3: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(async function() {
|
||||
await function() {
|
||||
try {
|
||||
FAIL;
|
||||
} catch (e) {
|
||||
return console.log("foo");
|
||||
} finally {
|
||||
console.log("bar");
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log("baz");
|
||||
}
|
||||
expect: {
|
||||
(async function() {
|
||||
await function() {
|
||||
try {
|
||||
FAIL;
|
||||
} catch (e) {
|
||||
return console.log("foo");
|
||||
} finally {
|
||||
console.log("bar");
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log("baz");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5528_4: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(async function() {
|
||||
await function() {
|
||||
try {
|
||||
return {
|
||||
then() {
|
||||
console.log("foo");
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
console.log("bar");
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log("baz");
|
||||
}
|
||||
expect: {
|
||||
(async function() {
|
||||
await function() {
|
||||
try {
|
||||
return {
|
||||
then() {
|
||||
console.log("foo");
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
console.log("bar");
|
||||
}
|
||||
}();
|
||||
})();
|
||||
console.log("baz");
|
||||
}
|
||||
expect_stdout: [
|
||||
"bar",
|
||||
"baz",
|
||||
"foo",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
@@ -762,3 +762,27 @@ issue_5228: {
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
issue_5469: {
|
||||
options = {
|
||||
assignments: true,
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
pure_getters: "strict",
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function f(a) {
|
||||
a && 42[a = A && null];
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function f(a) {
|
||||
a && A,
|
||||
0;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
@@ -241,6 +241,208 @@ class_super: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
static_init: {
|
||||
input: {
|
||||
var a = "foo";
|
||||
var b = null;
|
||||
class A {
|
||||
static {
|
||||
var a = "bar";
|
||||
b = true;
|
||||
var c = 42;
|
||||
console.log(a, b, c);
|
||||
}
|
||||
}
|
||||
console.log(a, b, typeof c);
|
||||
}
|
||||
expect_exact: 'var a="foo";var b=null;class A{static{var a="bar";b=true;var c=42;console.log(a,b,c)}}console.log(a,b,typeof c);'
|
||||
expect_stdout: [
|
||||
"bar true 42",
|
||||
"foo true undefined",
|
||||
]
|
||||
node_version: ">=16"
|
||||
}
|
||||
|
||||
static_field_init: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(class {
|
||||
static [console.log("foo")] = console.log("bar");
|
||||
static {
|
||||
console.log("baz");
|
||||
}
|
||||
static [console.log("moo")] = console.log("moz");
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
(class {
|
||||
static [(console.log("foo"), console.log("moo"))] = (
|
||||
console.log("bar"),
|
||||
(() => {
|
||||
console.log("baz");
|
||||
})(),
|
||||
console.log("moz")
|
||||
);
|
||||
});
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"moo",
|
||||
"bar",
|
||||
"baz",
|
||||
"moz",
|
||||
]
|
||||
node_version: ">=16"
|
||||
}
|
||||
|
||||
static_field_init_strict: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
(class {
|
||||
static [console.log("foo")] = console.log("bar");
|
||||
static {
|
||||
console.log("baz");
|
||||
}
|
||||
static [console.log("moo")] = console.log("moz");
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log("foo"),
|
||||
console.log("moo"),
|
||||
(() => (
|
||||
console.log("bar"),
|
||||
(() => {
|
||||
console.log("baz");
|
||||
})(),
|
||||
console.log("moz")
|
||||
))();
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"moo",
|
||||
"bar",
|
||||
"baz",
|
||||
"moz",
|
||||
]
|
||||
node_version: ">=16"
|
||||
}
|
||||
|
||||
static_init_side_effects_1: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL";
|
||||
(class {
|
||||
static {
|
||||
a = "PASS";
|
||||
}
|
||||
});
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "FAIL";
|
||||
(class {
|
||||
static {
|
||||
a = "PASS";
|
||||
}
|
||||
});
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=16"
|
||||
}
|
||||
|
||||
static_init_side_effects_1_strict: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var a = "FAIL";
|
||||
(class {
|
||||
static {
|
||||
a = "PASS";
|
||||
}
|
||||
});
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var a = "FAIL";
|
||||
(() => (() => {
|
||||
a = "PASS";
|
||||
})())();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=16"
|
||||
}
|
||||
|
||||
static_init_side_effects_2: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL";
|
||||
(class {
|
||||
static {
|
||||
a = "PASS";
|
||||
}
|
||||
});
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "FAIL";
|
||||
(class {
|
||||
static {
|
||||
a = "PASS";
|
||||
}
|
||||
});
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=16"
|
||||
}
|
||||
|
||||
static_init_side_effects_2_strict: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var a = "FAIL";
|
||||
(class {
|
||||
static {
|
||||
a = "PASS";
|
||||
}
|
||||
});
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var a = "FAIL";
|
||||
(() => (() => {
|
||||
a = "PASS";
|
||||
})())();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=16"
|
||||
}
|
||||
|
||||
block_scoped: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
@@ -341,7 +543,7 @@ drop_extends: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
keep_extends: {
|
||||
keep_extends_1: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
@@ -366,6 +568,43 @@ keep_extends: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
keep_extends_2: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
(class extends Function {});
|
||||
console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
(class extends Function {});
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
keep_extends_3: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
class A extends Function {}
|
||||
console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
(class extends Function {});
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
drop_name: {
|
||||
options = {
|
||||
unused: true,
|
||||
@@ -670,6 +909,58 @@ single_use_7: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
single_use_extends: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
class A extends class B {
|
||||
f() {
|
||||
return "PASS";
|
||||
}
|
||||
} {}
|
||||
console.log(new A().f());
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log(new class extends class {
|
||||
f() {
|
||||
return "PASS";
|
||||
}
|
||||
} {}().f());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
single_use_extends_non_strict: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
class A extends class B {
|
||||
f() {
|
||||
return "PASS";
|
||||
}
|
||||
} {}
|
||||
console.log(new A().f());
|
||||
}
|
||||
expect: {
|
||||
console.log(new class extends class {
|
||||
f() {
|
||||
return "PASS";
|
||||
}
|
||||
} {}().f());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
collapse_non_strict: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
@@ -742,6 +1033,38 @@ collapse_rhs_static: {
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
inline_non_strict: {
|
||||
options = {
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
return a.p = "PASS";
|
||||
}
|
||||
class A {
|
||||
g() {
|
||||
return f(42);
|
||||
}
|
||||
}
|
||||
console.log(new A().g());
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
return a.p = "PASS";
|
||||
}
|
||||
console.log(new class {
|
||||
g() {
|
||||
return f(42);
|
||||
}
|
||||
}().g());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
self_comparison: {
|
||||
options = {
|
||||
booleans: true,
|
||||
@@ -943,6 +1266,105 @@ keep_fnames: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
instanceof_lambda: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
console.log(42 instanceof class {});
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log(false);
|
||||
}
|
||||
expect_stdout: "false"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
drop_instanceof: {
|
||||
options = {
|
||||
booleans: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
class A {}
|
||||
console.log({} instanceof A, Math instanceof A);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log(!1, (Math, !1));
|
||||
}
|
||||
expect_stdout: "false false"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
keep_instanceof_1: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
class A {}
|
||||
var A;
|
||||
console.log({} instanceof A, Math instanceof A);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
class A {}
|
||||
var A;
|
||||
console.log({} instanceof A, Math instanceof A);
|
||||
}
|
||||
expect_stdout: SyntaxError("Identifier has already been declared")
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
keep_instanceof_2: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var A = Object;
|
||||
class A {}
|
||||
console.log({} instanceof A, Math instanceof A);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var A = Object;
|
||||
class A {}
|
||||
console.log({} instanceof A, Math instanceof A);
|
||||
}
|
||||
expect_stdout: SyntaxError("Identifier has already been declared")
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
keep_instanceof_3: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
class A {}
|
||||
A = Object;
|
||||
console.log({} instanceof A, Math instanceof A);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
class A {}
|
||||
A = Object;
|
||||
console.log({} instanceof A, Math instanceof A);
|
||||
}
|
||||
expect_stdout: "true true"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_805_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
@@ -1758,12 +2180,14 @@ issue_4962_1: {
|
||||
})(function g() {});
|
||||
}
|
||||
expect: {
|
||||
(function g() {}),
|
||||
void class {
|
||||
static c = function() {
|
||||
(function() {
|
||||
function f() {
|
||||
while (console.log(typeof g));
|
||||
}();
|
||||
};
|
||||
}
|
||||
(class {
|
||||
static c = f();
|
||||
});
|
||||
})(function g() {});
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=12"
|
||||
@@ -1796,6 +2220,37 @@ issue_4962_1_strict: {
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
issue_4962_1_strict_direct: {
|
||||
options = {
|
||||
ie: true,
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
function f() {
|
||||
"use strict";
|
||||
while (console.log(typeof g));
|
||||
}
|
||||
class A {
|
||||
static p = f();
|
||||
}
|
||||
})(function g() {});
|
||||
}
|
||||
expect: {
|
||||
(function g() {}),
|
||||
void class {
|
||||
static c = function() {
|
||||
"use strict";
|
||||
while (console.log(typeof g));
|
||||
}();
|
||||
};
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
issue_4962_2: {
|
||||
options = {
|
||||
ie: true,
|
||||
@@ -1815,8 +2270,11 @@ issue_4962_2: {
|
||||
}
|
||||
expect: {
|
||||
console.log(function f() {}(function g() {
|
||||
function h() {
|
||||
f;
|
||||
}
|
||||
(class {
|
||||
static c = f;
|
||||
static c = h();
|
||||
});
|
||||
}));
|
||||
}
|
||||
@@ -1852,6 +2310,69 @@ issue_4962_2_strict: {
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
issue_4962_2_strict_direct: {
|
||||
options = {
|
||||
ie: true,
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function f() {}(function g() {
|
||||
function h() {
|
||||
"use strict";
|
||||
f;
|
||||
}
|
||||
class A {
|
||||
static p = h();
|
||||
}
|
||||
}, typeof g));
|
||||
}
|
||||
expect: {
|
||||
console.log(function f() {}(function g() {
|
||||
(class {
|
||||
static c = function() {
|
||||
"use strict";
|
||||
f;
|
||||
}();
|
||||
});
|
||||
}));
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
issue_4962_2_strict_direct_inline: {
|
||||
options = {
|
||||
directives: true,
|
||||
ie: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function f() {}(function g() {
|
||||
function h() {
|
||||
"use strict";
|
||||
f;
|
||||
}
|
||||
class A {
|
||||
static p = h();
|
||||
}
|
||||
}, typeof g));
|
||||
}
|
||||
expect: {
|
||||
console.log(function f() {}(function g() {
|
||||
(class {
|
||||
static c = f;
|
||||
});
|
||||
}));
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
issue_4982_1: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
@@ -2541,7 +3062,7 @@ issue_5387: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5389: {
|
||||
issue_5389_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
toplevel: true,
|
||||
@@ -2572,6 +3093,37 @@ issue_5389: {
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
issue_5389_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
function log(m, n) {
|
||||
console.log(m, n);
|
||||
}
|
||||
var a = log;
|
||||
var A = class {
|
||||
[a = "FAIL"] = a = "PASS";
|
||||
};
|
||||
var b = new A();
|
||||
log(a, b.FAIL);
|
||||
}
|
||||
expect: {
|
||||
function log(m, n) {
|
||||
console.log(m, n);
|
||||
}
|
||||
var a = log;
|
||||
var A;
|
||||
var b = new class {
|
||||
[a = "FAIL"] = a = "PASS";
|
||||
}();
|
||||
log(a, b.FAIL);
|
||||
}
|
||||
expect_stdout: "PASS PASS"
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
issue_5436: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
@@ -2601,3 +3153,290 @@ issue_5436: {
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
issue_5481: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var a = "FAIL 1", log = console.log;
|
||||
try {
|
||||
a = "PASS";
|
||||
(class extends 42 {});
|
||||
log("FAIL 2", a);
|
||||
} catch (e) {
|
||||
log(a);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var a = "FAIL 1", log = console.log;
|
||||
try {
|
||||
a = "PASS";
|
||||
(class extends 42 {});
|
||||
log("FAIL 2", a);
|
||||
} catch (e) {
|
||||
log(a);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5489: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(class {
|
||||
[console.log("foo")];
|
||||
static {
|
||||
console.log("bar");
|
||||
}
|
||||
static [console.log("baz")]() {}
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
(class {
|
||||
[(console.log("foo"), console.log("baz"))];
|
||||
static {
|
||||
console.log("bar");
|
||||
}
|
||||
});
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"baz",
|
||||
"bar",
|
||||
]
|
||||
node_version: ">=16"
|
||||
}
|
||||
|
||||
issue_5489_strict: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
(class {
|
||||
[console.log("foo")];
|
||||
static {
|
||||
console.log("bar");
|
||||
}
|
||||
static [console.log("baz")]() {}
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log("foo"),
|
||||
console.log("baz"),
|
||||
(() => (() => {
|
||||
console.log("bar");
|
||||
})())();
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"baz",
|
||||
"bar",
|
||||
]
|
||||
node_version: ">=16"
|
||||
}
|
||||
|
||||
issue_5502: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var a = "FAIL";
|
||||
class A {
|
||||
static p = a;
|
||||
[a = "PASS"];
|
||||
}
|
||||
try {
|
||||
b++;
|
||||
} finally {
|
||||
var a, b = 42;
|
||||
}
|
||||
console.log(a, b);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var a = "FAIL";
|
||||
class A {
|
||||
static p = a;
|
||||
[a = "PASS"];
|
||||
}
|
||||
try {
|
||||
b++;
|
||||
} finally {
|
||||
var a, b = 42;
|
||||
}
|
||||
console.log(a, b);
|
||||
}
|
||||
expect_stdout: "PASS 42"
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
issue_5504: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var a;
|
||||
console.log((a = 42, class {
|
||||
static p;
|
||||
}).p);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var a;
|
||||
console.log((a = 42, class {
|
||||
static p;
|
||||
}).p);
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
issue_5512: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
a = "PASS";
|
||||
class A {
|
||||
static {
|
||||
console.log(a);
|
||||
}
|
||||
static p = "PASS";
|
||||
}
|
||||
var a;
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
a = "PASS";
|
||||
class A {
|
||||
static {
|
||||
console.log(a);
|
||||
}
|
||||
static p = "PASS";
|
||||
}
|
||||
var a;
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=16"
|
||||
}
|
||||
|
||||
issue_5531_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
class A {
|
||||
p = function() {
|
||||
var a = function f() {
|
||||
if (!a)
|
||||
console.log("foo");
|
||||
return 42;
|
||||
}(a++);
|
||||
}();
|
||||
}
|
||||
new A();
|
||||
new A();
|
||||
}
|
||||
expect: {
|
||||
class A {
|
||||
p = function() {
|
||||
var a = function f() {
|
||||
if (!a)
|
||||
console.log("foo");
|
||||
return 42;
|
||||
}(a++);
|
||||
}();
|
||||
}
|
||||
new A();
|
||||
new A();
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"foo",
|
||||
]
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
issue_5531_2: {
|
||||
options = {
|
||||
inline: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
class A {
|
||||
static p = function() {
|
||||
var a = function f() {
|
||||
if (!a)
|
||||
console.log("foo");
|
||||
return 42;
|
||||
}(a++);
|
||||
}();
|
||||
}
|
||||
new A();
|
||||
new A();
|
||||
}
|
||||
expect: {
|
||||
class A {
|
||||
static p = (a = function f() {
|
||||
if (!a)
|
||||
console.log("foo");
|
||||
return 42;
|
||||
}(a++), void 0);
|
||||
}
|
||||
var a;
|
||||
new A();
|
||||
new A();
|
||||
}
|
||||
expect_stdout: "foo"
|
||||
node_version: ">=12"
|
||||
}
|
||||
|
||||
issue_5531_3: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
class A {
|
||||
static {
|
||||
(function() {
|
||||
var a = function f() {
|
||||
if (!a)
|
||||
console.log("foo");
|
||||
return 42;
|
||||
}(a++);
|
||||
})();
|
||||
}
|
||||
}
|
||||
new A();
|
||||
new A();
|
||||
}
|
||||
expect: {
|
||||
class A {
|
||||
static {
|
||||
a = function f() {
|
||||
if (!a)
|
||||
console.log("foo");
|
||||
return 42;
|
||||
}(a++),
|
||||
void 0;
|
||||
var a;
|
||||
}
|
||||
}
|
||||
new A();
|
||||
new A();
|
||||
}
|
||||
expect_stdout: "foo"
|
||||
node_version: ">=16"
|
||||
}
|
||||
|
||||
@@ -40,6 +40,22 @@ unsafe_comps: {
|
||||
}
|
||||
}
|
||||
|
||||
unsafe_in_instanceof: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
unsafe_comps: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
42 in a;
|
||||
f() instanceof "foo";
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
f();
|
||||
}
|
||||
}
|
||||
|
||||
dont_change_in_or_instanceof_expressions: {
|
||||
input: {
|
||||
1 in 1;
|
||||
|
||||
@@ -1855,3 +1855,54 @@ issue_5338: {
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_5476: {
|
||||
mangle = {
|
||||
keep_fargs: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(n) {
|
||||
const a = 42;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function(n) {
|
||||
const o = 42;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
issue_5516: {
|
||||
options = {
|
||||
inline: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(typeof function() {
|
||||
try {} catch (a) {
|
||||
(function f() {
|
||||
a;
|
||||
})();
|
||||
}
|
||||
{
|
||||
const a = function() {};
|
||||
return a;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(typeof function() {
|
||||
try {} catch (a) {
|
||||
void a;
|
||||
}
|
||||
{
|
||||
const a = function() {};
|
||||
return a;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
@@ -1669,3 +1669,41 @@ issue_5106_2: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5506: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
(function(a) {
|
||||
var b = 1;
|
||||
(function f() {
|
||||
try {
|
||||
b-- && f();
|
||||
} catch (c) {}
|
||||
console.log(a);
|
||||
a = 42 in (a = "bar");
|
||||
})();
|
||||
})("foo");
|
||||
} catch (e) {}
|
||||
}
|
||||
expect: {
|
||||
try {
|
||||
(function(a) {
|
||||
var b = 1;
|
||||
(function f() {
|
||||
try {
|
||||
b-- && f();
|
||||
} catch (c) {}
|
||||
console.log(a);
|
||||
a = 42 in (a = "bar");
|
||||
})();
|
||||
})("foo");
|
||||
} catch (e) {}
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -541,7 +541,7 @@ inline_side_effects_2: {
|
||||
}
|
||||
expect: {
|
||||
var a = 42;
|
||||
[ [].e = --a ] = [ console ];
|
||||
[ [][0] = --a ] = [ console ];
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "42"
|
||||
@@ -1558,7 +1558,7 @@ issue_4502_4: {
|
||||
(function(a, b = console.log("FAIL")) {})(..."" + console.log(42));
|
||||
}
|
||||
expect: {
|
||||
[ , [].e = console.log("FAIL") ] = [ ..."" + console.log(42) ];
|
||||
[ , [][0] = console.log("FAIL") ] = [ ..."" + console.log(42) ];
|
||||
}
|
||||
expect_stdout: "42"
|
||||
node_version: ">=6"
|
||||
@@ -2183,7 +2183,7 @@ issue_5340_2: {
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
[ [].e = 0 ] = [ ({ p: a } = true).q ];
|
||||
[ [][0] = 0 ] = [ ({ p: a } = true).q ];
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
@@ -2239,3 +2239,593 @@ issue_5407: {
|
||||
]
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5444_1: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = 42;
|
||||
var b = function({} = setImmediate(function() {
|
||||
console.log(a++);
|
||||
})) {
|
||||
return this;
|
||||
}();
|
||||
console.log(typeof b);
|
||||
}
|
||||
expect: {
|
||||
var a = 42;
|
||||
var b = function({} = setImmediate(function() {
|
||||
console.log(a++);
|
||||
})) {
|
||||
return this;
|
||||
}();
|
||||
console.log(typeof b);
|
||||
}
|
||||
expect_stdout: [
|
||||
"object",
|
||||
"42",
|
||||
]
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5444_2: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b = a++) {
|
||||
return b;
|
||||
}
|
||||
console.log(f("FAIL") || "PASS");
|
||||
}
|
||||
expect: {
|
||||
function f(a, b = a++) {
|
||||
return b;
|
||||
}
|
||||
console.log(f("FAIL") || "PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5444_3: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b = function(c = a *= this) {
|
||||
return c;
|
||||
}()) {
|
||||
return b;
|
||||
}
|
||||
console.log(f("FAIL") || "PASS");
|
||||
}
|
||||
expect: {
|
||||
function f(a, b = function(c = a *= this) {
|
||||
return c;
|
||||
}()) {
|
||||
return b;
|
||||
}
|
||||
console.log(f("FAIL") || "PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5448_1: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(a = typeof console.log) {
|
||||
do {
|
||||
var b = [ ...a ];
|
||||
} while (console.log("PASS"));
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function(a = console.log) {
|
||||
do {} while (console.log("PASS"));
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5448_2: {
|
||||
options = {
|
||||
keep_fargs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(a = typeof console) {
|
||||
do {
|
||||
var b = [ ...a ];
|
||||
} while (console.log("PASS"));
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function(a = 0) {
|
||||
do {} while (console.log("PASS"));
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5448_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unsafe: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var [ a = typeof console ] = [ void console.log("PASS") ];
|
||||
var b = [ ...a ];
|
||||
}
|
||||
expect: {
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5448_4: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unsafe: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var { p: a = typeof console } = { p: void console.log("PASS") };
|
||||
var b = [ ...a ];
|
||||
}
|
||||
expect: {
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5463: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
if (console.log("PASS"))
|
||||
var a = void 0,
|
||||
b = void 0,
|
||||
b = ([ a = FAIL ] = b && b);
|
||||
}
|
||||
expect: {
|
||||
var a, b, b;
|
||||
console.log("PASS") && (
|
||||
b = a = void 0,
|
||||
b = [a = FAIL] = a && a
|
||||
);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5465: {
|
||||
options = {
|
||||
inline: true,
|
||||
merge_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b) {
|
||||
(function(c = b = "FAIL 2") {
|
||||
this && console.log(b || "PASS");
|
||||
})(42 - a && a);
|
||||
}
|
||||
f("FAIL 1");
|
||||
}
|
||||
expect: {
|
||||
a = "FAIL 1",
|
||||
void function(c = b = "FAIL 2") {
|
||||
this && console.log(b || "PASS");
|
||||
}(42 - a && a);
|
||||
var a, b;
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5485: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
(function f(f, a = console.log(void 0 === f ? "PASS" : "FAIL")) {})();
|
||||
}
|
||||
expect: {
|
||||
(function f(f, a = console.log(void 0 === f ? "PASS" : "FAIL")) {})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_1_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(b = 42) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_1_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(b = 42) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_2_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f([ b ] = []) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;) {
|
||||
var [ [] = [] ] = [];
|
||||
throw "PASS";
|
||||
}
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_2_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f([ b ] = []) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;) {
|
||||
var [ [] = [] ] = [];
|
||||
throw "PASS";
|
||||
}
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_3_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(b = 42, c = null) {
|
||||
c;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_3_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(b = 42, c = null) {
|
||||
c;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_4_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(b = 42, [ c ] = []) {
|
||||
c;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;) {
|
||||
var [ [] = [] ] = [];
|
||||
throw "PASS";
|
||||
}
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_4_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(b = 42, [ c ] = []) {
|
||||
c;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;) {
|
||||
var [ [] = [] ] = [];
|
||||
throw "PASS";
|
||||
}
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5536: {
|
||||
options = {
|
||||
inline: true,
|
||||
keep_fargs: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function*() {
|
||||
(([], a = 42) => {})([]);
|
||||
console.log(typeof a);
|
||||
})().next();
|
||||
}
|
||||
expect: {
|
||||
(function*() {
|
||||
[ , [][0] = 0 ] = [ [] ],
|
||||
void 0;
|
||||
console.log(typeof a);
|
||||
})().next();
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
@@ -1848,8 +1848,8 @@ issue_4294: {
|
||||
}) {}({
|
||||
[a]: 0,
|
||||
});
|
||||
var a = A;
|
||||
console.log(a);
|
||||
var b = A;
|
||||
console.log(b);
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
@@ -3020,6 +3020,7 @@ issue_5074_method_pure_getters: {
|
||||
issue_5085_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unsafe: true,
|
||||
@@ -3032,8 +3033,7 @@ issue_5085_1: {
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
var b = [ 42 ][0];
|
||||
b;
|
||||
42;
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
@@ -3043,6 +3043,7 @@ issue_5085_1: {
|
||||
issue_5085_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unsafe: true,
|
||||
@@ -3059,7 +3060,7 @@ issue_5085_2: {
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
(function(b) {
|
||||
b = [ 42 ][0];
|
||||
0;
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
@@ -3400,7 +3401,7 @@ issue_5222: {
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5288: {
|
||||
issue_5288_1: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
inline: true,
|
||||
@@ -3420,7 +3421,37 @@ issue_5288: {
|
||||
}() ]));
|
||||
}
|
||||
expect: {
|
||||
while (console ? console.log("PASS") : 0, void 0);
|
||||
while (function() {
|
||||
if (console)
|
||||
console.log("PASS");
|
||||
}(), void 0);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5288_2: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
inline: true,
|
||||
keep_fargs: false,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
varify: true,
|
||||
}
|
||||
input: {
|
||||
while (function([]) {}([ function f() {
|
||||
if (console)
|
||||
return console.log("PASS");
|
||||
else {
|
||||
let a = 0;
|
||||
}
|
||||
}() ]));
|
||||
}
|
||||
expect: {
|
||||
while (console && console.log("PASS"), void 0);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
@@ -3466,7 +3497,7 @@ issue_5314_2: {
|
||||
A = this;
|
||||
new function() {
|
||||
[ {
|
||||
[console.log(this === A ? "FAIL" : "PASS")]: [].e,
|
||||
[console.log(this === A ? "FAIL" : "PASS")]: [][0],
|
||||
} ] = [ 42 ];
|
||||
}();
|
||||
}
|
||||
@@ -3566,3 +3597,136 @@ issue_5423: {
|
||||
expect_stdout: "function"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5454: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
var a = 42, a = {
|
||||
p: [ a ] = [],
|
||||
};
|
||||
return "PASS";
|
||||
}
|
||||
console.log(f());
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a) {
|
||||
a = 42, a = {
|
||||
p: [ a ] = [],
|
||||
};
|
||||
return "PASS";
|
||||
}());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5485: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
(function f({
|
||||
p: f,
|
||||
[console.log(void 0 === f ? "PASS" : "FAIL")]: a,
|
||||
}) {})(42);
|
||||
}
|
||||
expect: {
|
||||
(function f({
|
||||
p: f,
|
||||
[console.log(void 0 === f ? "PASS" : "FAIL")]: a,
|
||||
}) {})(42);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f([ b ]) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})([]);
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f([ b ]) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})([]);
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
@@ -671,6 +671,76 @@ iife: {
|
||||
}
|
||||
}
|
||||
|
||||
drop_instanceof: {
|
||||
options = {
|
||||
booleans: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {}
|
||||
console.log({} instanceof f, Math instanceof f);
|
||||
}
|
||||
expect: {
|
||||
console.log(!1, (Math, !1));
|
||||
}
|
||||
expect_stdout: "false false"
|
||||
}
|
||||
|
||||
keep_instanceof_1: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {}
|
||||
var f;
|
||||
console.log({} instanceof f, Math instanceof f);
|
||||
}
|
||||
expect: {
|
||||
function f() {}
|
||||
var f;
|
||||
console.log({} instanceof f, Math instanceof f);
|
||||
}
|
||||
expect_stdout: "false false"
|
||||
}
|
||||
|
||||
keep_instanceof_2: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {}
|
||||
var f = Object;
|
||||
console.log({} instanceof f, Math instanceof f);
|
||||
}
|
||||
expect: {
|
||||
function f() {}
|
||||
var f = Object;
|
||||
console.log({} instanceof f, Math instanceof f);
|
||||
}
|
||||
expect_stdout: "true true"
|
||||
}
|
||||
|
||||
keep_instanceof_3: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
f = Object;
|
||||
function f() {}
|
||||
console.log({} instanceof f, Math instanceof f);
|
||||
}
|
||||
expect: {
|
||||
f = Object;
|
||||
function f() {}
|
||||
console.log({} instanceof f, Math instanceof f);
|
||||
}
|
||||
expect_stdout: "true true"
|
||||
}
|
||||
|
||||
issue_1539: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
@@ -3615,3 +3685,85 @@ issue_5271: {
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
issue_5533_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(b) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5533_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(b) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -907,6 +907,20 @@ chained_side_effects: {
|
||||
]
|
||||
}
|
||||
|
||||
instanceof_lambda: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
console.log(42 instanceof function() {});
|
||||
}
|
||||
expect: {
|
||||
console.log(false);
|
||||
}
|
||||
expect_stdout: "false"
|
||||
}
|
||||
|
||||
issue_1649: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
|
||||
@@ -417,6 +417,46 @@ hoist_funs: {
|
||||
expect_exact: "export function f(){}export default async function*g(){}"
|
||||
}
|
||||
|
||||
instanceof_default_class: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
export default class A {
|
||||
f(a) {
|
||||
return a instanceof A;
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
export default class A {
|
||||
f(a) {
|
||||
return a instanceof A;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
instanceof_default_function: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
export default function f() {
|
||||
if (!(this instanceof f))
|
||||
throw new Error("must instantiate");
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
export default function f() {
|
||||
if (!(this instanceof f))
|
||||
throw new Error("must instantiate");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_4742_join_vars_1: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
@@ -496,3 +536,16 @@ issue_4766: {
|
||||
export var a = "bar";
|
||||
}
|
||||
}
|
||||
|
||||
issue_5444: {
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
export var a = (console, console);
|
||||
}
|
||||
expect: {
|
||||
console;
|
||||
export var a = console;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -629,7 +629,7 @@ inline_binary_and: {
|
||||
return void "moo";
|
||||
return;
|
||||
} else
|
||||
return;
|
||||
return void 0;
|
||||
}());
|
||||
}
|
||||
expect_stdout: [
|
||||
@@ -5582,7 +5582,7 @@ issue_3835: {
|
||||
return f();
|
||||
})();
|
||||
}
|
||||
expect_stdout: true
|
||||
expect_stdout: RangeError("Maximum call stack size exceeded")
|
||||
}
|
||||
|
||||
issue_3836_1: {
|
||||
@@ -7835,7 +7835,7 @@ issue_5249_1: {
|
||||
while (console.log("FAIL 2"));
|
||||
return;
|
||||
} else
|
||||
return;
|
||||
return void 0;
|
||||
throw "FAIL 3";
|
||||
}());
|
||||
}
|
||||
@@ -8398,3 +8398,251 @@ issue_5409: {
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
mixed_mode_inline_1: {
|
||||
options = {
|
||||
directives: true,
|
||||
inline: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
return this;
|
||||
}
|
||||
console.log(function() {
|
||||
return f();
|
||||
}() ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
return this;
|
||||
}() ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
mixed_mode_inline_1_strict: {
|
||||
options = {
|
||||
directives: true,
|
||||
inline: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function f() {
|
||||
return this;
|
||||
}
|
||||
console.log(function() {
|
||||
return f();
|
||||
}() ? "FAIL" : "PASS");
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log(function() {
|
||||
return this;
|
||||
}() ? "FAIL" : "PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
mixed_mode_inline_2: {
|
||||
options = {
|
||||
directives: true,
|
||||
inline: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
"use strict";
|
||||
return this;
|
||||
}
|
||||
console.log(function() {
|
||||
return f();
|
||||
}() ? "FAIL" : "PASS");
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
"use strict";
|
||||
return this;
|
||||
}() ? "FAIL" : "PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
mixed_mode_inline_2_strict: {
|
||||
options = {
|
||||
directives: true,
|
||||
inline: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function f() {
|
||||
"use strict";
|
||||
return this;
|
||||
}
|
||||
console.log(function() {
|
||||
return f();
|
||||
}() ? "FAIL" : "PASS");
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log(function() {
|
||||
return this;
|
||||
}() ? "FAIL" : "PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
mixed_mode_inline_3: {
|
||||
options = {
|
||||
directives: true,
|
||||
inline: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
return this;
|
||||
}
|
||||
console.log(function() {
|
||||
"use strict";
|
||||
return f();
|
||||
}() ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
return this;
|
||||
}
|
||||
console.log(function() {
|
||||
"use strict";
|
||||
return f();
|
||||
}() ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
mixed_mode_inline_3_strict: {
|
||||
options = {
|
||||
directives: true,
|
||||
inline: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function f() {
|
||||
return this;
|
||||
}
|
||||
console.log(function() {
|
||||
"use strict";
|
||||
return f();
|
||||
}() ? "FAIL" : "PASS");
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log(function() {
|
||||
return this;
|
||||
}() ? "FAIL" : "PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
mixed_mode_inline_4: {
|
||||
options = {
|
||||
directives: true,
|
||||
inline: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
"use strict";
|
||||
return this;
|
||||
}
|
||||
console.log(function() {
|
||||
"use strict";
|
||||
return f();
|
||||
}() ? "FAIL" : "PASS");
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
"use strict";
|
||||
return function() {
|
||||
"use strict";
|
||||
return this;
|
||||
}();
|
||||
}() ? "FAIL" : "PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
mixed_mode_inline_4_strict: {
|
||||
options = {
|
||||
directives: true,
|
||||
inline: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function f() {
|
||||
"use strict";
|
||||
return this;
|
||||
}
|
||||
console.log(function() {
|
||||
"use strict";
|
||||
return f();
|
||||
}() ? "FAIL" : "PASS");
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log(function() {
|
||||
return this;
|
||||
}() ? "FAIL" : "PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
module_inline: {
|
||||
options = {
|
||||
inline: true,
|
||||
module: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
var a = f;
|
||||
function f() {
|
||||
return a;
|
||||
}
|
||||
console.log(f() === a);
|
||||
}
|
||||
expect: {
|
||||
var a = f;
|
||||
function f() {
|
||||
return a;
|
||||
}
|
||||
console.log(a === a);
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
@@ -1176,3 +1176,51 @@ issue_5182: {
|
||||
"42",
|
||||
]
|
||||
}
|
||||
|
||||
issue_5441: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
(function() {
|
||||
a = { p: this };
|
||||
})();
|
||||
return typeof a;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a) {
|
||||
(function() {
|
||||
a_p = this;
|
||||
})();
|
||||
var a_p;
|
||||
return typeof {};
|
||||
}());
|
||||
}
|
||||
expect_stdout: "object"
|
||||
}
|
||||
|
||||
issue_5498: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
__proto__: 42,
|
||||
};
|
||||
while (console.log(typeof o.__proto__));
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
__proto__: 42,
|
||||
};
|
||||
while (console.log(typeof o.__proto__));
|
||||
}
|
||||
expect_stdout: "object"
|
||||
}
|
||||
|
||||
@@ -850,3 +850,170 @@ issue_866_2: {
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
identical_returns_1: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
if (console.log("foo"))
|
||||
return 42;
|
||||
else
|
||||
while (console.log("bar"));
|
||||
return 42;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
if (!console.log("foo"))
|
||||
while (console.log("bar"));
|
||||
return 42;
|
||||
}());
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"42",
|
||||
]
|
||||
}
|
||||
|
||||
identical_returns_2: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
if (console.log("foo"))
|
||||
while (console.log("FAIL"));
|
||||
else
|
||||
return "bar";
|
||||
return "bar";
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
if (console.log("foo"))
|
||||
while (console.log("FAIL"));
|
||||
return "bar";
|
||||
}());
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
}
|
||||
|
||||
identical_returns_3: {
|
||||
options = {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
if (a)
|
||||
return 42;
|
||||
if (a)
|
||||
return;
|
||||
return 42;
|
||||
}
|
||||
if (f(console))
|
||||
console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
if (a)
|
||||
return 42;
|
||||
if (a)
|
||||
;
|
||||
else
|
||||
return 42;
|
||||
}
|
||||
if (f(console))
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_4374: {
|
||||
options = {
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
console.log(f(console));
|
||||
function f(a) {
|
||||
if (console) return 0;
|
||||
if (a) return 1;
|
||||
return 0;
|
||||
}
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
console.log(function(a) {
|
||||
return !console && a ? 1 : 0;
|
||||
}(console));
|
||||
})();
|
||||
}
|
||||
expect_stdout: "0"
|
||||
}
|
||||
|
||||
issue_5521: {
|
||||
options = {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
if (console)
|
||||
try {
|
||||
return "FAIL";
|
||||
} finally {
|
||||
return;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
if (console)
|
||||
try {
|
||||
return "FAIL";
|
||||
} finally {
|
||||
return;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
issue_5523: {
|
||||
options = {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
if (console)
|
||||
try {
|
||||
FAIL;
|
||||
} finally {
|
||||
return;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
if (console)
|
||||
try {
|
||||
FAIL;
|
||||
} finally {
|
||||
return;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
@@ -111,6 +111,7 @@ labels_5: {
|
||||
labels_6: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
out: break out;
|
||||
@@ -208,6 +209,59 @@ labels_10: {
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
labels_11: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
L: if (console.log("PASS"))
|
||||
break L;
|
||||
}
|
||||
expect: {
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
labels_12: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
L: try {
|
||||
if (console.log("foo"))
|
||||
break L;
|
||||
throw "bar";
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
break L;
|
||||
} finally {
|
||||
if (console.log("baz"))
|
||||
break L;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
L: try {
|
||||
if (!console.log("foo"))
|
||||
throw "bar";
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
} finally {
|
||||
if (console.log("baz"))
|
||||
break L;
|
||||
}
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
}
|
||||
|
||||
issue_4466_1: {
|
||||
mangle = {
|
||||
v8: false,
|
||||
@@ -327,3 +381,53 @@ issue_4466_2_toplevel_v8: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5522: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
L: try {
|
||||
return "FAIL";
|
||||
} finally {
|
||||
break L;
|
||||
}
|
||||
return "PASS";
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
L: try {
|
||||
return "FAIL";
|
||||
} finally {
|
||||
break L;
|
||||
}
|
||||
return "PASS";
|
||||
}());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5524: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
L: try {
|
||||
FAIL;
|
||||
} finally {
|
||||
break L;
|
||||
}
|
||||
console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
L: try {
|
||||
FAIL;
|
||||
} finally {
|
||||
break L;
|
||||
}
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -892,6 +892,40 @@ if_return_2: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
if_return_3: {
|
||||
options = {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var a = "PASS";
|
||||
function f(b) {
|
||||
if (console) {
|
||||
let b = a;
|
||||
return b;
|
||||
} else
|
||||
while (console.log("FAIL 1"));
|
||||
return b;
|
||||
}
|
||||
console.log(f("FAIL 2"));
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var a = "PASS";
|
||||
function f(b) {
|
||||
if (console) {
|
||||
let b = a;
|
||||
return b;
|
||||
} else
|
||||
while (console.log("FAIL 1"));
|
||||
return b;
|
||||
}
|
||||
console.log(f("FAIL 2"));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
do_if_continue_1: {
|
||||
options = {
|
||||
if_return: true,
|
||||
@@ -1604,48 +1638,6 @@ issue_4305_2: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_1753: {
|
||||
mangle = {
|
||||
toplevel: false,
|
||||
webkit: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
let l = null;
|
||||
for (let i = 0; i < 1; i++)
|
||||
console.log(i);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
let l = null;
|
||||
for (let i = 0; i < 1; i++)
|
||||
console.log(i);
|
||||
}
|
||||
expect_stdout: "0"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_1753_toplevel: {
|
||||
mangle = {
|
||||
toplevel: true,
|
||||
webkit: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
let l = null;
|
||||
for (let i = 0; i < 1; i++)
|
||||
console.log(i);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
let l = null;
|
||||
for (let e = 0; e < 1; e++)
|
||||
console.log(e);
|
||||
}
|
||||
expect_stdout: "0"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_4438: {
|
||||
options = {
|
||||
if_return: true,
|
||||
@@ -2020,3 +2012,23 @@ issue_5338: {
|
||||
expect_stdout: ReferenceError("a is not defined")
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5476: {
|
||||
mangle = {
|
||||
keep_fargs: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
console.log(function(n) {
|
||||
let a;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log(function(n) {
|
||||
let o;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
@@ -3732,3 +3732,116 @@ issue_5420: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5451: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
A = 1;
|
||||
var a = 1, b;
|
||||
console.log(function f() {
|
||||
return a-- && f(b = A, b);
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
A = 1;
|
||||
var a = 1, b;
|
||||
console.log(function f() {
|
||||
return a-- && f(b = A, b);
|
||||
}());
|
||||
}
|
||||
expect_stdout: "0"
|
||||
}
|
||||
|
||||
issue_5471_1: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
inline: true,
|
||||
merge_vars: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL 1";
|
||||
function f(b, c) {
|
||||
function g() {
|
||||
if (console)
|
||||
return 42;
|
||||
else
|
||||
c = "FAIL 2";
|
||||
}
|
||||
var d = g();
|
||||
console.log(c || "PASS");
|
||||
var e = function h() {
|
||||
while (b && e);
|
||||
}();
|
||||
}
|
||||
f(a++) && a;
|
||||
}
|
||||
expect: {
|
||||
var a = "FAIL 1";
|
||||
var b, c, e;
|
||||
b = +a,
|
||||
function() {
|
||||
if (console)
|
||||
return;
|
||||
c = "FAIL 2";
|
||||
}(),
|
||||
console.log(c || "PASS"),
|
||||
e = function() {
|
||||
while (b && e);
|
||||
}();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5471_2: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
merge_vars: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL 1";
|
||||
function f(b, c) {
|
||||
function g() {
|
||||
if (console)
|
||||
return 42;
|
||||
else
|
||||
c = "FAIL 2";
|
||||
}
|
||||
var d = g();
|
||||
console.log(c || "PASS");
|
||||
var e = function h() {
|
||||
while (b && e);
|
||||
}();
|
||||
}
|
||||
f(a++) && a;
|
||||
}
|
||||
expect: {
|
||||
var a = "FAIL 1";
|
||||
var b, c, e;
|
||||
b = +a,
|
||||
function() {
|
||||
if (console)
|
||||
return;
|
||||
c = "FAIL 2";
|
||||
}(),
|
||||
console.log(c || "PASS"),
|
||||
e = function() {
|
||||
while (b && e);
|
||||
}(),
|
||||
void 0;
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -308,6 +308,7 @@ issue_4679: {
|
||||
issue_5266: {
|
||||
options = {
|
||||
inline: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
[
|
||||
|
||||
@@ -147,7 +147,7 @@ relational: {
|
||||
"bar" >= "bar";
|
||||
}
|
||||
expect: {
|
||||
bar();
|
||||
0 instanceof bar();
|
||||
bar();
|
||||
bar(), bar();
|
||||
bar();
|
||||
|
||||
@@ -50,6 +50,22 @@ regexp_properties: {
|
||||
expect_stdout: "abc true false 0 false"
|
||||
}
|
||||
|
||||
instanceof_1: {
|
||||
input: {
|
||||
console.log(/foo/ instanceof RegExp);
|
||||
}
|
||||
expect_exact: "console.log(/foo/ instanceof RegExp);"
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
instanceof_2: {
|
||||
input: {
|
||||
console.log(42 + /foo/ instanceof Object);
|
||||
}
|
||||
expect_exact: "console.log(42+/foo/ instanceof Object);"
|
||||
expect_stdout: "false"
|
||||
}
|
||||
|
||||
issue_3434_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
|
||||
@@ -648,7 +648,7 @@ drop_new_function: {
|
||||
}
|
||||
expect: {
|
||||
void ([ ... {
|
||||
[console.log("PASS")]: [].e,
|
||||
[console.log("PASS")]: [][0],
|
||||
}] = []);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
@@ -1363,3 +1363,171 @@ issue_5391: {
|
||||
expect_stdout: "NaN"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
issue_5533_1_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(...b) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_1_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(...b) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_2_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(...[ b ]) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_2_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(...[ b ]) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
@@ -645,3 +645,56 @@ issue_4751: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
drop_instanceof: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
42 instanceof function() {};
|
||||
console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
drop_instanceof_reference: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
function f() {}
|
||||
42 instanceof f;
|
||||
console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
function f() {}
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
retain_instanceof: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
42 instanceof "foo";
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
try {
|
||||
0 instanceof "foo";
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ if_return: {
|
||||
if (w) {
|
||||
if (y) return;
|
||||
} else if (z) return;
|
||||
return x == y || (x && w(), y && z()), !0;
|
||||
return x != y && (x && w(), y && z()), !0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ hoist_props_const: {
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var o = 0, o_p = "PASS";
|
||||
var o, o_p = "PASS";
|
||||
console.log(o_p);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
@@ -613,3 +613,35 @@ issue_4954: {
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5516: {
|
||||
options = {
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
varify: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
console.log(typeof function() {
|
||||
{
|
||||
let a;
|
||||
}
|
||||
{
|
||||
const a = function() {};
|
||||
return a;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log(typeof function() {
|
||||
{
|
||||
const a = function() {};
|
||||
return a;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect_stdout: "function"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
@@ -107,3 +107,209 @@ function_name_mangle_ie8: {
|
||||
expect_exact: "(function(){console.log(typeof function n(o){})})();"
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
issue_1753: {
|
||||
mangle = {
|
||||
toplevel: false,
|
||||
webkit: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
let l = null;
|
||||
for (let i = 0; i < 1; i++)
|
||||
console.log(i);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
let l = null;
|
||||
for (let i = 0; i < 1; i++)
|
||||
console.log(i);
|
||||
}
|
||||
expect_stdout: "0"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_1753_toplevel: {
|
||||
mangle = {
|
||||
toplevel: true,
|
||||
webkit: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
let l = null;
|
||||
for (let i = 0; i < 1; i++)
|
||||
console.log(i);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
let l = null;
|
||||
for (let e = 0; e < 1; e++)
|
||||
console.log(e);
|
||||
}
|
||||
expect_stdout: "0"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5032_await: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
webkit: false,
|
||||
}
|
||||
input: {
|
||||
function log(value) {
|
||||
console.log(value);
|
||||
return value;
|
||||
}
|
||||
async function f(a) {
|
||||
var b = log(a), c = b;
|
||||
log(b);
|
||||
log(c);
|
||||
}
|
||||
f("PASS");
|
||||
}
|
||||
expect: {
|
||||
function log(value) {
|
||||
console.log(value);
|
||||
return value;
|
||||
}
|
||||
async function f(a) {
|
||||
var a = log(a), c = a;
|
||||
log(a);
|
||||
log(c);
|
||||
}
|
||||
f("PASS");
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5032_await_webkit: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
webkit: true,
|
||||
}
|
||||
input: {
|
||||
function log(value) {
|
||||
console.log(value);
|
||||
return value;
|
||||
}
|
||||
async function f(a) {
|
||||
var b = log(a), c = b;
|
||||
log(b);
|
||||
log(c);
|
||||
}
|
||||
f("PASS");
|
||||
}
|
||||
expect: {
|
||||
function log(value) {
|
||||
console.log(value);
|
||||
return value;
|
||||
}
|
||||
async function f(a) {
|
||||
var b = log(a), c = b;
|
||||
log(b);
|
||||
log(c);
|
||||
}
|
||||
f("PASS");
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5032_yield: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
webkit: false,
|
||||
}
|
||||
input: {
|
||||
function log(value) {
|
||||
console.log(value);
|
||||
return value;
|
||||
}
|
||||
function *f(a) {
|
||||
var b = log(a), c = b;
|
||||
log(b);
|
||||
log(c);
|
||||
}
|
||||
f("PASS").next();
|
||||
}
|
||||
expect: {
|
||||
function log(value) {
|
||||
console.log(value);
|
||||
return value;
|
||||
}
|
||||
function *f(a) {
|
||||
var a = log(a), c = a;
|
||||
log(a);
|
||||
log(c);
|
||||
}
|
||||
f("PASS").next();
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5032_yield_webkit: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
webkit: true,
|
||||
}
|
||||
input: {
|
||||
function log(value) {
|
||||
console.log(value);
|
||||
return value;
|
||||
}
|
||||
function *f(a) {
|
||||
var b = log(a), c = b;
|
||||
log(b);
|
||||
log(c);
|
||||
}
|
||||
f("PASS").next();
|
||||
}
|
||||
expect: {
|
||||
function log(value) {
|
||||
console.log(value);
|
||||
return value;
|
||||
}
|
||||
function *f(a) {
|
||||
var b = log(a), c = b;
|
||||
log(b);
|
||||
log(c);
|
||||
}
|
||||
f("PASS").next();
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5480: {
|
||||
mangle = {
|
||||
webkit: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
L: for (let a in console.log("PASS"));
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
o: for (let o in console.log("PASS"));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
@@ -907,7 +907,7 @@ drop_body: {
|
||||
})([ console.log("baz") ]);
|
||||
}
|
||||
expect: {
|
||||
[ [ , [].e = console.log("foo") ] ] = [ [ console.log("baz") ] ];
|
||||
[ [ , [][0] = console.log("foo") ] ] = [ [ console.log("baz") ] ];
|
||||
}
|
||||
expect_stdout: [
|
||||
"baz",
|
||||
@@ -934,6 +934,21 @@ drop_unused_call: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
instanceof_lambda: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
console.log(42 instanceof function*() {});
|
||||
}
|
||||
expect: {
|
||||
console.log(false);
|
||||
}
|
||||
expect_stdout: "false"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_4454_1: {
|
||||
rename = false
|
||||
options = {
|
||||
@@ -978,8 +993,8 @@ issue_4454_2: {
|
||||
expect: {
|
||||
function f(a) {
|
||||
(function*(c = console.log(a)) {})();
|
||||
var a = 42..toString();
|
||||
console.log(a);
|
||||
var b = 42..toString();
|
||||
console.log(b);
|
||||
}
|
||||
f("PASS");
|
||||
}
|
||||
@@ -1267,80 +1282,6 @@ issue_5019_2: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5032_normal: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
webkit: false,
|
||||
}
|
||||
input: {
|
||||
function log(value) {
|
||||
console.log(value);
|
||||
return value;
|
||||
}
|
||||
function *f(a) {
|
||||
var b = log(a), c = b;
|
||||
log(b);
|
||||
log(c);
|
||||
}
|
||||
f("PASS").next();
|
||||
}
|
||||
expect: {
|
||||
function log(value) {
|
||||
console.log(value);
|
||||
return value;
|
||||
}
|
||||
function *f(a) {
|
||||
var a = log(a), c = a;
|
||||
log(a);
|
||||
log(c);
|
||||
}
|
||||
f("PASS").next();
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5032_webkit: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
webkit: true,
|
||||
}
|
||||
input: {
|
||||
function log(value) {
|
||||
console.log(value);
|
||||
return value;
|
||||
}
|
||||
function *f(a) {
|
||||
var b = log(a), c = b;
|
||||
log(b);
|
||||
log(c);
|
||||
}
|
||||
f("PASS").next();
|
||||
}
|
||||
expect: {
|
||||
function log(value) {
|
||||
console.log(value);
|
||||
return value;
|
||||
}
|
||||
function *f(a) {
|
||||
var b = log(a), c = b;
|
||||
log(b);
|
||||
log(c);
|
||||
}
|
||||
f("PASS").next();
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5034: {
|
||||
options = {
|
||||
functions: true,
|
||||
@@ -1526,6 +1467,80 @@ issue_5385_2: {
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_5385_3: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(async function*() {
|
||||
return function() {
|
||||
try {
|
||||
throw console.log("foo");
|
||||
} catch (e) {
|
||||
return console.log("bar");
|
||||
}
|
||||
}();
|
||||
})().next();
|
||||
console.log("moo");
|
||||
}
|
||||
expect: {
|
||||
(async function*() {
|
||||
try {
|
||||
throw console.log("foo");
|
||||
} catch (e) {
|
||||
return console.log("bar");
|
||||
}
|
||||
return void 0;
|
||||
})().next();
|
||||
console.log("moo");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"moo",
|
||||
]
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_5385_4: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(async function*() {
|
||||
return async function() {
|
||||
try {
|
||||
return {
|
||||
then(resolve) {
|
||||
resolve(console.log("FAIL"));
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
return "PASS";
|
||||
}
|
||||
}();
|
||||
})().next().then(o => console.log(o.value, o.done));
|
||||
}
|
||||
expect: {
|
||||
(async function*() {
|
||||
return async function() {
|
||||
try {
|
||||
return {
|
||||
then(resolve) {
|
||||
resolve(console.log("FAIL"));
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
return "PASS";
|
||||
}
|
||||
}();
|
||||
})().next().then(o => console.log(o.value, o.done));
|
||||
}
|
||||
expect_stdout: "PASS true"
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_5425: {
|
||||
options = {
|
||||
assignments: true,
|
||||
@@ -1547,3 +1562,113 @@ issue_5425: {
|
||||
expect_stdout: "PASS undefined"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5456: {
|
||||
options = {
|
||||
inline: true,
|
||||
merge_vars: true,
|
||||
}
|
||||
input: {
|
||||
var a = true;
|
||||
(function() {
|
||||
(function(b, c) {
|
||||
var d = function*() {
|
||||
c = null;
|
||||
}();
|
||||
var e = function() {
|
||||
if (c)
|
||||
console.log(typeof d);
|
||||
while (b);
|
||||
}();
|
||||
})(function(i) {
|
||||
return console.log("foo") && i;
|
||||
}(a));
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
var a = true;
|
||||
(function() {
|
||||
b = (i = a, console.log("foo") && i),
|
||||
d = function*() {
|
||||
c = null;
|
||||
}(),
|
||||
e = function() {
|
||||
if (c) console.log(typeof d);
|
||||
while (b);
|
||||
}(),
|
||||
void 0;
|
||||
var b, c, d, e;
|
||||
var i;
|
||||
})();
|
||||
}
|
||||
expect_stdout: "foo"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5506: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
var b = function*() {
|
||||
a = null in (a = "PASS");
|
||||
}();
|
||||
try {
|
||||
b.next();
|
||||
} catch (e) {
|
||||
return a;
|
||||
}
|
||||
}("FAIL"));
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a) {
|
||||
var b = function*() {
|
||||
a = null in (a = "PASS");
|
||||
}();
|
||||
try {
|
||||
b.next();
|
||||
} catch (e) {
|
||||
return a;
|
||||
}
|
||||
}("FAIL"));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5526: {
|
||||
options = {
|
||||
inline: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(async function*() {
|
||||
try {
|
||||
return function() {
|
||||
while (console.log("foo"));
|
||||
}();
|
||||
} finally {
|
||||
console.log("bar");
|
||||
}
|
||||
})().next();
|
||||
console.log("baz");
|
||||
}
|
||||
expect: {
|
||||
(async function*() {
|
||||
try {
|
||||
while (console.log("foo"));
|
||||
return void 0;
|
||||
} finally {
|
||||
console.log("bar");
|
||||
}
|
||||
})().next();
|
||||
console.log("baz");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"baz",
|
||||
"bar",
|
||||
]
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
1
test/input/module/expect.js
Normal file
1
test/input/module/expect.js
Normal file
@@ -0,0 +1 @@
|
||||
function n(){return this||arguments[0]+arguments[1]}function o(){return this||arguments[0]+arguments[1]}console.log(n(n(1,3),5)),console.log(o(o(2,4),6));
|
||||
13
test/input/module/input.js
Normal file
13
test/input/module/input.js
Normal file
@@ -0,0 +1,13 @@
|
||||
console.log(function() {
|
||||
function sum(...params) {
|
||||
return this || arguments[0] + arguments[1];
|
||||
}
|
||||
return sum(sum(1, 3), 5);
|
||||
}());
|
||||
console.log(function() {
|
||||
"use strict";
|
||||
function sum(...params) {
|
||||
return this || arguments[0] + arguments[1];
|
||||
}
|
||||
return sum(sum(2, 4), 6);
|
||||
}());
|
||||
@@ -928,6 +928,14 @@ describe("bin/uglifyjs", function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should work with --module", function(done) {
|
||||
var command = uglifyjscmd + " test/input/module/input.js --module -mc";
|
||||
exec(command, function(err, stdout, stderr) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, read("test/input/module/expect.js"));
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should compress swarm of unused variables with reasonable performance", function(done) {
|
||||
var code = [
|
||||
"console.log(function() {",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
var assert = require("assert");
|
||||
var readFileSync = require("fs").readFileSync;
|
||||
var run_code = require("../sandbox").run_code;
|
||||
var semver = require("semver");
|
||||
var UglifyJS = require("../..");
|
||||
|
||||
function read(path) {
|
||||
@@ -320,6 +321,24 @@ describe("minify", function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe("module", function() {
|
||||
it("Should not inline `await` variables", function() {
|
||||
if (semver.satisfies(process.version, "<8")) return;
|
||||
var code = [
|
||||
"console.log(function() {",
|
||||
" return typeof await;",
|
||||
"}());",
|
||||
].join("\n");
|
||||
assert.strictEqual(run_code("(async function(){" + code + "})();"), "undefined\n");
|
||||
var result = UglifyJS.minify(code, {
|
||||
module: true,
|
||||
});
|
||||
if (result.error) throw result.error;
|
||||
assert.strictEqual(result.code, "console.log(function(){return typeof await}());");
|
||||
assert.strictEqual(run_code("(async function(){" + result.code + "})();"), "undefined\n");
|
||||
});
|
||||
});
|
||||
|
||||
describe("rename", function() {
|
||||
it("Should be repeatable", function() {
|
||||
var code = "!function(x){return x(x)}(y);";
|
||||
|
||||
@@ -210,10 +210,10 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
||||
}
|
||||
if (node.expression instanceof U.AST_Function) {
|
||||
// hoist and return expressions from the IIFE function expression
|
||||
var seq = [];
|
||||
var scope = tt.find_parent(U.AST_Scope), seq = [];
|
||||
node.expression.body.forEach(function(node) {
|
||||
var expr = node instanceof U.AST_Exit ? node.value : node.body;
|
||||
if (expr instanceof U.AST_Node && !U.is_statement(expr) && can_hoist(expr)) {
|
||||
if (expr instanceof U.AST_Node && !U.is_statement(expr) && can_hoist(expr, scope)) {
|
||||
// collect expressions from each statement's body
|
||||
seq.push(expr);
|
||||
}
|
||||
@@ -264,11 +264,12 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
||||
CHANGED = true;
|
||||
return List.skip;
|
||||
default:
|
||||
if (!has_exit(node) && can_hoist(node)) {
|
||||
if (can_hoist(node, tt.find_parent(U.AST_Scope))) {
|
||||
// hoist function declaration body
|
||||
var body = node.body;
|
||||
node.body = [];
|
||||
body.push(node); // retain function with empty body to be dropped later
|
||||
// retain function with empty body to be dropped later
|
||||
body.push(node);
|
||||
CHANGED = true;
|
||||
return List.splice(body);
|
||||
}
|
||||
@@ -382,7 +383,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
||||
if (node.body instanceof U.AST_Call && node.body.expression instanceof U.AST_Function) {
|
||||
// hoist simple statement IIFE function expression body
|
||||
node.start._permute++;
|
||||
if (!has_exit(node.body.expression) && can_hoist(node.body.expression)) {
|
||||
if (can_hoist(node.body.expression, tt.find_parent(U.AST_Scope))) {
|
||||
CHANGED = true;
|
||||
return List.splice(node.body.expression.body);
|
||||
}
|
||||
@@ -647,21 +648,6 @@ function trim_trailing_whitespace(value) {
|
||||
return ("" + value).replace(/\s+$/, "");
|
||||
}
|
||||
|
||||
function has_exit(fn) {
|
||||
var found = false;
|
||||
var tw = new U.TreeWalker(function(node) {
|
||||
if (found) return found;
|
||||
if (node instanceof U.AST_Exit) {
|
||||
return found = true;
|
||||
}
|
||||
if (node instanceof U.AST_Scope && node !== fn) {
|
||||
return true; // don't descend into nested functions
|
||||
}
|
||||
});
|
||||
fn.walk(tw);
|
||||
return found;
|
||||
}
|
||||
|
||||
function has_loopcontrol(body, loop, label) {
|
||||
var found = false;
|
||||
var tw = new U.TreeWalker(function(node) {
|
||||
@@ -676,17 +662,31 @@ function has_loopcontrol(body, loop, label) {
|
||||
return found;
|
||||
}
|
||||
|
||||
function can_hoist(body) {
|
||||
function can_hoist(body, scope) {
|
||||
var found = false;
|
||||
body.walk(new U.TreeWalker(function(node) {
|
||||
var tw = new U.TreeWalker(function(node) {
|
||||
if (found) return true;
|
||||
if (node instanceof U.AST_Exit) return found = true;
|
||||
if (node instanceof U.AST_NewTarget) return found = true;
|
||||
if (node instanceof U.AST_Scope) {
|
||||
if (node === body) return;
|
||||
if (node instanceof U.AST_Arrow || node instanceof U.AST_AsyncArrow) node.argnames.forEach(function(sym) {
|
||||
sym.walk(tw);
|
||||
});
|
||||
// don't descend into nested functions
|
||||
return true;
|
||||
}
|
||||
if (node instanceof U.AST_Super) return found = true;
|
||||
}));
|
||||
if (node instanceof U.AST_SymbolDeclaration || node instanceof U.AST_SymbolRef) switch (node.name) {
|
||||
case "await":
|
||||
if (/^Async/.test(scope.TYPE)) return found = true;
|
||||
return;
|
||||
case "yield":
|
||||
if (/Generator/.test(scope.TYPE)) return found = true;
|
||||
return;
|
||||
}
|
||||
});
|
||||
body.walk(tw);
|
||||
return !found;
|
||||
}
|
||||
|
||||
@@ -760,9 +760,9 @@ function compare_run_code(code, minify_options, result_cache, max_timeout) {
|
||||
if (minified.error) return minified;
|
||||
|
||||
var toplevel = sandbox.has_toplevel(minify_options);
|
||||
var unminified = run_code(code, toplevel, result_cache, max_timeout);
|
||||
var unminified = run(code, max_timeout);
|
||||
var timeout = Math.min(100 * unminified.elapsed, max_timeout);
|
||||
var minified_result = run_code(minified.code, toplevel, result_cache, timeout).result;
|
||||
var minified_result = run(minified.code, timeout).result;
|
||||
|
||||
if (sandbox.same_stdout(unminified.result, minified_result)) {
|
||||
return is_timed_out(unminified.result) && is_timed_out(minified_result) && {
|
||||
@@ -774,6 +774,16 @@ function compare_run_code(code, minify_options, result_cache, max_timeout) {
|
||||
minified_result: minified_result,
|
||||
elapsed: unminified.elapsed,
|
||||
};
|
||||
|
||||
function run(code, timeout) {
|
||||
if (minify_options.module) code = [
|
||||
'"use strict";',
|
||||
"(async()=>{",
|
||||
code,
|
||||
'})().catch(e=>process.on("exit",()=>{throw e}));',
|
||||
].join("\n");
|
||||
return run_code(code, toplevel, result_cache, timeout);
|
||||
}
|
||||
}
|
||||
|
||||
function test_minify(code, minify_options) {
|
||||
|
||||
@@ -54,7 +54,7 @@ ERR=$?; if [ "$ERR" != "0" ]; then echo "Error: $ERR"; exit $ERR; fi
|
||||
minify_in_situ "src" \
|
||||
&& minify_in_situ "third_party" \
|
||||
&& rm -rf node_modules \
|
||||
&& npm_install \
|
||||
&& npm_install --package-lock \
|
||||
&& rm -rf build/* \
|
||||
&& npm run build:terser-bundled \
|
||||
&& npm run build:uglify-js-bundled \
|
||||
|
||||
@@ -140,6 +140,7 @@ var SUPPORT = function(matrix) {
|
||||
class: "class C { f() {} }",
|
||||
class_field: "class C { p = 0; }",
|
||||
class_private: "class C { #f() {} }",
|
||||
class_static_init: "class C { static {} }",
|
||||
computed_key: "({[0]: 0});",
|
||||
const_block: "var a; { const a = 0; }",
|
||||
default_value: "[ a = 0 ] = [];",
|
||||
@@ -252,7 +253,7 @@ BINARY_OPS = BINARY_OPS.concat(BINARY_OPS);
|
||||
if (SUPPORT.exponentiation) BINARY_OPS.push("**");
|
||||
BINARY_OPS = BINARY_OPS.concat(BINARY_OPS);
|
||||
BINARY_OPS = BINARY_OPS.concat(BINARY_OPS);
|
||||
BINARY_OPS.push(" in ");
|
||||
BINARY_OPS.push(" in ", " instanceof ");
|
||||
|
||||
var ASSIGNMENTS = [ "=" ];
|
||||
ASSIGNMENTS = ASSIGNMENTS.concat(ASSIGNMENTS);
|
||||
@@ -405,7 +406,7 @@ function createTopLevelCode() {
|
||||
unique_vars.length = 0;
|
||||
classes.length = 0;
|
||||
allow_this = true;
|
||||
async = false;
|
||||
async = SUPPORT.async && rng(200) == 0;
|
||||
has_await = false;
|
||||
export_default = false;
|
||||
generator = false;
|
||||
@@ -413,7 +414,7 @@ function createTopLevelCode() {
|
||||
funcs = 0;
|
||||
clazz = 0;
|
||||
imports = 0;
|
||||
in_class = 0;
|
||||
in_class = async;
|
||||
called = Object.create(null);
|
||||
var s = [
|
||||
strictMode(),
|
||||
@@ -1181,7 +1182,11 @@ function createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn
|
||||
unique_vars.length = unique_len;
|
||||
});
|
||||
}
|
||||
if (n !== 0) s += " finally { " + createStatements(3, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) + " }";
|
||||
if (n !== 0) s += [
|
||||
" finally { ",
|
||||
createStatements(rng(5) + 1, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth),
|
||||
" }",
|
||||
].join("");
|
||||
return s;
|
||||
case STMT_C:
|
||||
return "c = c + 1;";
|
||||
@@ -1805,7 +1810,7 @@ function createClassLiteral(recurmax, stmtDepth, canThrow, name) {
|
||||
if (canThrow && rng(20) == 0) {
|
||||
s += p;
|
||||
} else {
|
||||
s += "(" + p + " && " + p + ".constructor === Function ? " + p + " : function() {})";
|
||||
s += "(typeof " + p + ' == "function" && typeof ' + p + '.prototype == "object" && ' + p + ".constructor === Function ? " + p + " : function() {})";
|
||||
}
|
||||
}
|
||||
s += " {\n";
|
||||
@@ -1826,19 +1831,29 @@ function createClassLiteral(recurmax, stmtDepth, canThrow, name) {
|
||||
if (SUPPORT.class_field && rng(2)) {
|
||||
if (internal) {
|
||||
s += internal;
|
||||
} else if (fixed && bug_static_class_field) {
|
||||
} else if (fixed && bug_class_static_nontrivial) {
|
||||
s += getDotKey();
|
||||
} else {
|
||||
s += createObjectKey(recurmax, stmtDepth, canThrow);
|
||||
}
|
||||
if (rng(5)) {
|
||||
async = bug_async_class_await && fixed && 0;
|
||||
async = false;
|
||||
generator = false;
|
||||
s += " = " + createExpression(recurmax, NO_COMMA, stmtDepth, fixed ? canThrow : CANNOT_THROW);
|
||||
generator = save_generator;
|
||||
async = save_async;
|
||||
}
|
||||
s += ";\n";
|
||||
} else if (SUPPORT.class_static_init && fixed && !internal && rng(10) == 0) {
|
||||
async = false;
|
||||
generator = false;
|
||||
s += [
|
||||
"{ ",
|
||||
createStatements(rng(5) + 1, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CANNOT_RETURN, stmtDepth),
|
||||
" }\n",
|
||||
].join("");
|
||||
generator = save_generator;
|
||||
async = save_async;
|
||||
} else {
|
||||
if (!fixed && !internal && constructor && rng(10) == 0) {
|
||||
internal = constructor;
|
||||
@@ -1994,7 +2009,7 @@ function createBinaryOp(noComma, canThrow) {
|
||||
var op;
|
||||
do {
|
||||
op = BINARY_OPS[rng(BINARY_OPS.length)];
|
||||
} while (noComma && op == "," || !canThrow && op == " in ");
|
||||
} while (noComma && op == "," || !canThrow && /^ in/.test(op));
|
||||
return op;
|
||||
}
|
||||
|
||||
@@ -2037,7 +2052,7 @@ function isBannedKeyword(name) {
|
||||
case "let":
|
||||
return in_class;
|
||||
case "await":
|
||||
return async !== false;
|
||||
return async || in_class && bug_class_static_await;
|
||||
case "yield":
|
||||
return generator || in_class;
|
||||
}
|
||||
@@ -2087,6 +2102,12 @@ if (require.main !== module) {
|
||||
}
|
||||
|
||||
function run_code(code, toplevel, timeout) {
|
||||
if (async && has_await) code = [
|
||||
'"use strict";',
|
||||
"(async()=>{",
|
||||
code,
|
||||
'})().catch(e=>process.on("exit",()=>{throw e}));',
|
||||
].join("\n");
|
||||
return sandbox.run_code(sandbox.patch_module_statements(code), toplevel, timeout);
|
||||
}
|
||||
|
||||
@@ -2106,7 +2127,9 @@ function errorln(msg) {
|
||||
}
|
||||
|
||||
function try_beautify(code, toplevel, result, printfn, options) {
|
||||
var beautified = UglifyJS.minify(code, JSON.parse(beautify_options));
|
||||
var o = JSON.parse(beautify_options);
|
||||
if (async && has_await) o.module = true;
|
||||
var beautified = UglifyJS.minify(code, o);
|
||||
if (beautified.error) {
|
||||
printfn("// !!! beautify failed !!!");
|
||||
printfn(beautified.error);
|
||||
@@ -2259,12 +2282,27 @@ function log(options) {
|
||||
}
|
||||
|
||||
function sort_globals(code) {
|
||||
var globals = run_code("throw Object.keys(this).sort(" + function(global) {
|
||||
var injected = "throw Object.keys(this).sort(" + function(global) {
|
||||
return function(m, n) {
|
||||
return (typeof global[n] == "function") - (typeof global[m] == "function")
|
||||
|| (m < n ? -1 : m > n ? 1 : 0);
|
||||
};
|
||||
} + "(this));\n" + code);
|
||||
} + "(this));";
|
||||
var save_async = async;
|
||||
if (async && has_await) {
|
||||
async = false;
|
||||
injected = [
|
||||
'"use strict";',
|
||||
injected,
|
||||
"(async function(){",
|
||||
code,
|
||||
"})();"
|
||||
].join("\n");
|
||||
} else {
|
||||
injected += "\n" + code;
|
||||
}
|
||||
var globals = run_code(injected);
|
||||
async = save_async;
|
||||
if (!Array.isArray(globals)) {
|
||||
errorln();
|
||||
errorln();
|
||||
@@ -2324,20 +2362,28 @@ function is_error_in(ex) {
|
||||
return ex.name == "TypeError" && /'in'/.test(ex.message);
|
||||
}
|
||||
|
||||
function is_error_tdz(ex) {
|
||||
return ex.name == "ReferenceError";
|
||||
}
|
||||
|
||||
function is_error_spread(ex) {
|
||||
return ex.name == "TypeError" && /Found non-callable @@iterator| is not iterable| not a function/.test(ex.message);
|
||||
return ex.name == "TypeError" && /Found non-callable @@iterator| is not iterable| not a function|Symbol\(Symbol\.iterator\)/.test(ex.message);
|
||||
}
|
||||
|
||||
function is_error_recursion(ex) {
|
||||
return ex.name == "RangeError" && /Invalid string length|Maximum call stack size exceeded/.test(ex.message);
|
||||
}
|
||||
|
||||
function is_error_set_property(ex) {
|
||||
return ex.name == "TypeError" && /^Cannot set propert[\s\S]+? of (null|undefined)/.test(ex.message);
|
||||
}
|
||||
|
||||
function is_error_redeclaration(ex) {
|
||||
return ex.name == "SyntaxError" && /already been declared|redeclaration/.test(ex.message);
|
||||
}
|
||||
|
||||
function is_error_destructuring(ex) {
|
||||
return ex.name == "TypeError" && /^Cannot destructure /.test(ex.message);
|
||||
return ex.name == "TypeError" && /^Cannot (destructure|read propert)/.test(ex.message);
|
||||
}
|
||||
|
||||
function is_error_class_constructor(ex) {
|
||||
@@ -2351,6 +2397,8 @@ function is_error_getter_only_property(ex) {
|
||||
}
|
||||
|
||||
function patch_try_catch(orig, toplevel) {
|
||||
var patched = Object.create(null);
|
||||
var patches = [];
|
||||
var stack = [ {
|
||||
code: orig,
|
||||
index: 0,
|
||||
@@ -2388,7 +2436,7 @@ function patch_try_catch(orig, toplevel) {
|
||||
"throw " + match[1] + ";",
|
||||
].join("\n");
|
||||
}
|
||||
var new_code = code.slice(0, index) + insert + code.slice(index) + tail_throw;
|
||||
var new_code = code.slice(0, index) + insert + code.slice(index) + tail_throw + "var UFUZZ_ERROR;";
|
||||
var result = run_code(new_code, toplevel);
|
||||
if (!sandbox.is_error(result)) {
|
||||
if (!stack.filled && match[1]) stack.push({
|
||||
@@ -2400,27 +2448,35 @@ function patch_try_catch(orig, toplevel) {
|
||||
offset += insert.length;
|
||||
code = new_code;
|
||||
} else if (is_error_in(result)) {
|
||||
index = result.ufuzz_catch;
|
||||
return orig.slice(0, index) + result.ufuzz_var + ' = new Error("invalid `in`");' + orig.slice(index);
|
||||
patch(result.ufuzz_catch, result.ufuzz_var + ' = new Error("invalid `in`");');
|
||||
} else if (is_error_tdz(result)) {
|
||||
patch(result.ufuzz_catch, result.ufuzz_var + ' = new Error("TDZ");');
|
||||
} else if (is_error_spread(result)) {
|
||||
index = result.ufuzz_catch;
|
||||
return orig.slice(0, index) + result.ufuzz_var + ' = new Error("spread not iterable");' + orig.slice(index);
|
||||
patch(result.ufuzz_catch, result.ufuzz_var + ' = new Error("spread not iterable");');
|
||||
} else if (is_error_recursion(result)) {
|
||||
index = result.ufuzz_try;
|
||||
return orig.slice(0, index) + 'throw new Error("skipping infinite recursion");' + orig.slice(index);
|
||||
patch(result.ufuzz_try, 'throw new Error("skipping infinite recursion");');
|
||||
} else if (is_error_set_property(result)) {
|
||||
patch(result.ufuzz_catch, result.ufuzz_var + ' = new Error("cannot set property");');
|
||||
} else if (is_error_destructuring(result)) {
|
||||
index = result.ufuzz_catch;
|
||||
return orig.slice(0, index) + result.ufuzz_var + ' = new Error("cannot destructure");' + orig.slice(index);
|
||||
patch(result.ufuzz_catch, result.ufuzz_var + ' = new Error("cannot destructure");');
|
||||
} else if (is_error_class_constructor(result)) {
|
||||
index = result.ufuzz_catch;
|
||||
return orig.slice(0, index) + result.ufuzz_var + ' = new Error("missing new for class");' + orig.slice(index);
|
||||
patch(result.ufuzz_catch, result.ufuzz_var + ' = new Error("missing new for class");');
|
||||
} else if (is_error_getter_only_property(result)) {
|
||||
index = result.ufuzz_catch;
|
||||
return orig.slice(0, index) + result.ufuzz_var + ' = new Error("setting getter-only property");' + orig.slice(index);
|
||||
patch(result.ufuzz_catch, result.ufuzz_var + ' = new Error("setting getter-only property");');
|
||||
}
|
||||
}
|
||||
stack.filled = true;
|
||||
}
|
||||
if (patches.length) return patches.reduce(function(code, patch) {
|
||||
var index = patch[0];
|
||||
return code.slice(0, index) + patch[1] + code.slice(index);
|
||||
}, orig);
|
||||
|
||||
function patch(index, code) {
|
||||
if (patched[index]) return;
|
||||
patched[index] = true;
|
||||
patches.unshift([ index, code ]);
|
||||
}
|
||||
}
|
||||
|
||||
var beautify_options = {
|
||||
@@ -2444,10 +2500,13 @@ if (SUPPORT.arrow && SUPPORT.async && SUPPORT.rest && sandbox.is_error(sandbox.r
|
||||
return ex.name == "SyntaxError" && ex.message == "Rest parameter must be last formal parameter";
|
||||
};
|
||||
}
|
||||
var bug_async_class_await = SUPPORT.async && SUPPORT.class_field && sandbox.is_error(sandbox.run_code("var await; async function f() { class A { static p = await; } }"));
|
||||
var bug_class_static_await = SUPPORT.async && SUPPORT.class_field && sandbox.is_error(sandbox.run_code("var await; class A { static p = await; }"));
|
||||
var bug_class_static_nontrivial = SUPPORT.class_field && sandbox.is_error(sandbox.run_code("class A { static 42; static get 42() {} }"));
|
||||
var bug_for_of_async = SUPPORT.for_await_of && sandbox.is_error(sandbox.run_code("var async; for (async of []);"));
|
||||
var bug_for_of_var = SUPPORT.for_of && SUPPORT.let && sandbox.is_error(sandbox.run_code("try {} catch (e) { for (var e of []); }"));
|
||||
var bug_static_class_field = SUPPORT.class_field && sandbox.is_error(sandbox.run_code("class A { static 42; static get 42() {} }"));
|
||||
var bug_proto_stream = function(ex) {
|
||||
return ex.name == "TypeError" && ex.message == "callback is not a function";
|
||||
}
|
||||
if (SUPPORT.destructuring && sandbox.is_error(sandbox.run_code("console.log([ 1 ], {} = 2);"))) {
|
||||
beautify_options.output.v8 = true;
|
||||
minify_options.forEach(function(o) {
|
||||
@@ -2478,11 +2537,17 @@ for (var round = 1; round <= num_iterations; round++) {
|
||||
println();
|
||||
// ignore v8 parser bug
|
||||
return bug_async_arrow_rest(result)
|
||||
// ignore Node.js `__proto__` quirks
|
||||
|| bug_proto_stream(result)
|
||||
// ignore runtime platform bugs
|
||||
|| result.message == "Script execution aborted.";
|
||||
})) continue;
|
||||
minify_options.forEach(function(options) {
|
||||
var o = JSON.parse(options);
|
||||
if (async && has_await) {
|
||||
o.module = true;
|
||||
options = JSON.stringify(o);
|
||||
}
|
||||
var toplevel = sandbox.has_toplevel(o);
|
||||
o.validate = true;
|
||||
uglify_code = UglifyJS.minify(original_code, o);
|
||||
@@ -2495,6 +2560,8 @@ for (var round = 1; round <= num_iterations; round++) {
|
||||
var uglify_erred = sandbox.is_error(uglify_result);
|
||||
// ignore v8 parser bug
|
||||
if (!ok && uglify_erred && bug_async_arrow_rest(uglify_result)) ok = true;
|
||||
// ignore Node.js `__proto__` quirks
|
||||
if (!ok && uglify_erred && bug_proto_stream(uglify_result)) ok = true;
|
||||
// ignore runtime platform bugs
|
||||
if (!ok && uglify_erred && uglify_result.message == "Script execution aborted.") ok = true;
|
||||
// handle difference caused by time-outs
|
||||
@@ -2532,55 +2599,34 @@ for (var round = 1; round <= num_iterations; round++) {
|
||||
ok = sandbox.same_stdout(fuzzy_result, uglify_result);
|
||||
}
|
||||
}
|
||||
// ignore difference in error message caused by Temporal Dead Zone
|
||||
if (!ok && original_erred && uglify_erred && original_result.name == "ReferenceError" && uglify_result.name == "ReferenceError") ok = true;
|
||||
// ignore difference due to implicit strict-mode in `class`
|
||||
if (!ok && /\bclass\b/.test(original_code)) {
|
||||
var original_strict = run_code('"use strict";\n' + original_code, toplevel);
|
||||
if (uglify_erred && /^(Syntax|Type)Error$/.test(uglify_result.name)) {
|
||||
ok = sandbox.is_error(original_strict);
|
||||
} else {
|
||||
ok = sandbox.same_stdout(original_strict, uglify_result);
|
||||
}
|
||||
}
|
||||
// ignore difference in error message caused by `import` symbol redeclaration
|
||||
if (!ok && original_erred && uglify_erred && /\bimport\b/.test(original_code)) {
|
||||
if (is_error_redeclaration(original_result) && is_error_redeclaration(uglify_result)) ok = true;
|
||||
}
|
||||
if (!ok && original_erred && uglify_erred && (
|
||||
// ignore difference in error message caused by `in`
|
||||
is_error_in(original_result) && is_error_in(uglify_result)
|
||||
// ignore difference in error message caused by Temporal Dead Zone
|
||||
|| is_error_tdz(original_result) && is_error_tdz(uglify_result)
|
||||
// ignore difference in error message caused by spread syntax
|
||||
|| is_error_spread(original_result) && is_error_spread(uglify_result)
|
||||
// ignore difference in error message caused by destructuring assignment
|
||||
|| is_error_set_property(original_result) && is_error_set_property(uglify_result)
|
||||
// ignore difference in error message caused by `import` symbol redeclaration
|
||||
|| /\bimport\b/.test(original_code) && is_error_redeclaration(original_result) && is_error_redeclaration(uglify_result)
|
||||
// ignore difference in error message caused by destructuring
|
||||
|| is_error_destructuring(original_result) && is_error_destructuring(uglify_result)
|
||||
// ignore difference in error message caused by call on class
|
||||
|| is_error_class_constructor(original_result) && is_error_class_constructor(uglify_result)
|
||||
// ignore difference in error message caused by setting getter-only property
|
||||
|| is_error_getter_only_property(original_result) && is_error_getter_only_property(uglify_result)
|
||||
)) ok = true;
|
||||
// ignore difference due to `__proto__` assignment
|
||||
if (!ok && /\b__proto__\b/.test(original_code)) {
|
||||
var original_proto = run_code("(" + patch_proto + ")();\n" + original_code, toplevel);
|
||||
var uglify_proto = run_code("(" + patch_proto + ")();\n" + uglify_code, toplevel);
|
||||
ok = sandbox.same_stdout(original_proto, uglify_proto);
|
||||
}
|
||||
// ignore difference in error message caused by `in`
|
||||
if (!ok && original_erred && uglify_erred) {
|
||||
if (is_error_in(original_result) && is_error_in(uglify_result)) ok = true;
|
||||
}
|
||||
// ignore difference in error message caused by spread syntax
|
||||
if (!ok && original_erred && uglify_erred) {
|
||||
if (is_error_spread(original_result) && is_error_spread(uglify_result)) ok = true;
|
||||
}
|
||||
// ignore difference in depth of termination caused by infinite recursion
|
||||
if (!ok && original_erred && is_error_recursion(original_result)) {
|
||||
if (!uglify_erred || is_error_recursion(uglify_result)) ok = true;
|
||||
}
|
||||
// ignore difference in error message caused by destructuring
|
||||
if (!ok && original_erred && uglify_erred) {
|
||||
if (is_error_destructuring(original_result) && is_error_destructuring(uglify_result)) ok = true;
|
||||
}
|
||||
// ignore difference in error message caused by call on class
|
||||
if (!ok && original_erred && uglify_erred) {
|
||||
if (is_error_class_constructor(original_result) && is_error_class_constructor(uglify_result)) {
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
// ignore difference in error message caused by setting getter-only property
|
||||
if (!ok && original_erred && uglify_erred) {
|
||||
if (is_error_getter_only_property(original_result) && is_error_getter_only_property(uglify_result)) {
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
// ignore errors above when caught by try-catch
|
||||
if (!ok) {
|
||||
var orig_skipped = patch_try_catch(original_code, toplevel);
|
||||
|
||||
Reference in New Issue
Block a user