Compare commits
49 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fc7678c115 | ||
|
|
b371dc2d1e | ||
|
|
56e9454f1f | ||
|
|
d67daa8314 | ||
|
|
f0120e90b6 | ||
|
|
ec4558be29 | ||
|
|
685ab357cc | ||
|
|
5792f30175 | ||
|
|
24443b6764 | ||
|
|
154edf0427 | ||
|
|
4778cf88e2 | ||
|
|
38bd4f65d0 | ||
|
|
0b808f6428 | ||
|
|
b2bc2e1173 | ||
|
|
80787ff7ef | ||
|
|
b92a89f325 | ||
|
|
902292f776 | ||
|
|
3dcf098468 | ||
|
|
d89f0965aa | ||
|
|
c8d98f4787 | ||
|
|
0207b46d70 | ||
|
|
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 |
47
README.md
47
README.md
@@ -519,7 +519,8 @@ if (result.error) throw result.error;
|
|||||||
Pass an object to specify custom [mangle property options](#mangle-properties-options).
|
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
|
- `module` (default: `false`) — set to `true` if you wish to process input as
|
||||||
ES module, i.e. implicit `"use strict";` alongside with `toplevel` enabled.
|
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
|
- `nameCache` (default: `null`) — pass an empty object `{}` or a previously
|
||||||
used `nameCache` object if you wish to cache mangled variable and
|
used `nameCache` object if you wish to cache mangled variable and
|
||||||
@@ -632,7 +633,13 @@ to be `false` and all symbol names will be omitted.
|
|||||||
|
|
||||||
- `bare_returns` (default: `false`) — support top level `return` statements
|
- `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
|
- `shebang` (default: `true`) — support `#!command` as the first line
|
||||||
|
|
||||||
@@ -811,8 +818,9 @@ to be `false` and all symbol names will be omitted.
|
|||||||
|
|
||||||
- `unsafe` (default: `false`) — apply "unsafe" transformations (discussion below)
|
- `unsafe` (default: `false`) — apply "unsafe" transformations (discussion below)
|
||||||
|
|
||||||
- `unsafe_comps` (default: `false`) — compress expressions like `a <= b` assuming
|
- `unsafe_comps` (default: `false`) — assume operands cannot be (coerced to) `NaN`
|
||||||
none of the operands can 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)`
|
- `unsafe_Function` (default: `false`) — compress and mangle `Function(args, code)`
|
||||||
when both `args` and `code` are string literals.
|
when both `args` and `code` are string literals.
|
||||||
@@ -1351,7 +1359,7 @@ To allow for better optimizations, the compiler makes various assumptions:
|
|||||||
// SyntaxError: The left-hand side of a for-of loop may not be 'async'.
|
// SyntaxError: The left-hand side of a for-of loop may not be 'async'.
|
||||||
```
|
```
|
||||||
UglifyJS may modify the input which in turn may suppress those errors.
|
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
|
- Some versions of Chrome and Node.js will give incorrect results with the
|
||||||
following:
|
following:
|
||||||
```javascript
|
```javascript
|
||||||
console.log({
|
console.log({
|
||||||
@@ -1360,9 +1368,15 @@ To allow for better optimizations, the compiler makes various assumptions:
|
|||||||
return "FAIL";
|
return "FAIL";
|
||||||
},
|
},
|
||||||
[42]: "PASS",
|
[42]: "PASS",
|
||||||
|
}[42], {
|
||||||
|
...console,
|
||||||
|
get 42() {
|
||||||
|
return "FAIL";
|
||||||
|
},
|
||||||
|
42: "PASS",
|
||||||
}[42]);
|
}[42]);
|
||||||
// Expected: "PASS"
|
// Expected: "PASS PASS"
|
||||||
// Actual: "FAIL"
|
// Actual: "PASS FAIL"
|
||||||
```
|
```
|
||||||
UglifyJS may modify the input which in turn may suppress those errors.
|
UglifyJS may modify the input which in turn may suppress those errors.
|
||||||
- Earlier versions of JavaScript will throw `TypeError` with the following:
|
- Earlier versions of JavaScript will throw `TypeError` with the following:
|
||||||
@@ -1415,9 +1429,20 @@ To allow for better optimizations, the compiler makes various assumptions:
|
|||||||
function f() {
|
function f() {
|
||||||
throw 42;
|
throw 42;
|
||||||
}
|
}
|
||||||
} catch (e) {}
|
} catch (e) {
|
||||||
console.log(typeof f);
|
console.log(typeof f, e);
|
||||||
// Expected: "function"
|
}
|
||||||
// Actual: "undefined"
|
// 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.
|
UglifyJS may modify the input which in turn may suppress those errors.
|
||||||
|
|||||||
290
lib/ast.js
290
lib/ast.js
@@ -109,6 +109,9 @@ var AST_Node = DEFNODE("Node", "start end", {
|
|||||||
start: "[AST_Token] The first token of this node",
|
start: "[AST_Token] The first token of this node",
|
||||||
end: "[AST_Token] The last token of this node"
|
end: "[AST_Token] The last token of this node"
|
||||||
},
|
},
|
||||||
|
equals: function(node) {
|
||||||
|
return this.TYPE == node.TYPE && this._equals(node);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
visitor.visit(this);
|
visitor.visit(this);
|
||||||
},
|
},
|
||||||
@@ -138,6 +141,7 @@ var AST_Node = DEFNODE("Node", "start end", {
|
|||||||
}, null);
|
}, null);
|
||||||
|
|
||||||
DEF_BITPROPS(AST_Node, [
|
DEF_BITPROPS(AST_Node, [
|
||||||
|
// AST_Node
|
||||||
"_optimized",
|
"_optimized",
|
||||||
"_squeezed",
|
"_squeezed",
|
||||||
// AST_Call
|
// AST_Call
|
||||||
@@ -172,6 +176,8 @@ DEF_BITPROPS(AST_Node, [
|
|||||||
"pure",
|
"pure",
|
||||||
// AST_Assign
|
// AST_Assign
|
||||||
"redundant",
|
"redundant",
|
||||||
|
// AST_Node
|
||||||
|
"single_use",
|
||||||
// AST_ClassProperty
|
// AST_ClassProperty
|
||||||
"static",
|
"static",
|
||||||
// AST_Call
|
// AST_Call
|
||||||
@@ -231,6 +237,24 @@ AST_Node.disable_validation = function() {
|
|||||||
while (restore = restore_transforms.pop()) restore();
|
while (restore = restore_transforms.pop()) restore();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function all_equals(k, l) {
|
||||||
|
return k.length == l.length && all(k, function(m, i) {
|
||||||
|
return m.equals(l[i]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function list_equals(s, t) {
|
||||||
|
return s.length == t.length && all(s, function(u, i) {
|
||||||
|
return u == t[i];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function prop_equals(u, v) {
|
||||||
|
if (u === v) return true;
|
||||||
|
if (u == null) return v == null;
|
||||||
|
return u instanceof AST_Node && v instanceof AST_Node && u.equals(v);
|
||||||
|
}
|
||||||
|
|
||||||
/* -----[ statements ]----- */
|
/* -----[ statements ]----- */
|
||||||
|
|
||||||
var AST_Statement = DEFNODE("Statement", null, {
|
var AST_Statement = DEFNODE("Statement", null, {
|
||||||
@@ -242,6 +266,7 @@ var AST_Statement = DEFNODE("Statement", null, {
|
|||||||
|
|
||||||
var AST_Debugger = DEFNODE("Debugger", null, {
|
var AST_Debugger = DEFNODE("Debugger", null, {
|
||||||
$documentation: "Represents a debugger statement",
|
$documentation: "Represents a debugger statement",
|
||||||
|
_equals: return_true,
|
||||||
}, AST_Statement);
|
}, AST_Statement);
|
||||||
|
|
||||||
var AST_Directive = DEFNODE("Directive", "quote value", {
|
var AST_Directive = DEFNODE("Directive", "quote value", {
|
||||||
@@ -250,6 +275,9 @@ var AST_Directive = DEFNODE("Directive", "quote value", {
|
|||||||
quote: "[string?] the original quote character",
|
quote: "[string?] the original quote character",
|
||||||
value: "[string] The value of this directive as a plain string (it's not an AST_String!)",
|
value: "[string] The value of this directive as a plain string (it's not an AST_String!)",
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.value == node.value;
|
||||||
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
if (this.quote != null) {
|
if (this.quote != null) {
|
||||||
if (typeof this.quote != "string") throw new Error("quote must be string");
|
if (typeof this.quote != "string") throw new Error("quote must be string");
|
||||||
@@ -260,7 +288,8 @@ var AST_Directive = DEFNODE("Directive", "quote value", {
|
|||||||
}, AST_Statement);
|
}, AST_Statement);
|
||||||
|
|
||||||
var AST_EmptyStatement = DEFNODE("EmptyStatement", null, {
|
var AST_EmptyStatement = DEFNODE("EmptyStatement", null, {
|
||||||
$documentation: "The empty statement (empty block or simply a semicolon)"
|
$documentation: "The empty statement (empty block or simply a semicolon)",
|
||||||
|
_equals: return_true,
|
||||||
}, AST_Statement);
|
}, AST_Statement);
|
||||||
|
|
||||||
function is_statement(node) {
|
function is_statement(node) {
|
||||||
@@ -291,6 +320,9 @@ var AST_SimpleStatement = DEFNODE("SimpleStatement", "body", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
body: "[AST_Node] an expression node (should not be instanceof AST_Statement)",
|
body: "[AST_Node] an expression node (should not be instanceof AST_Statement)",
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.body.equals(node.body);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -342,6 +374,9 @@ var AST_Block = DEFNODE("Block", "body", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
body: "[AST_Statement*] an array of statements"
|
body: "[AST_Statement*] an array of statements"
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return all_equals(this.body, node.body);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -376,6 +411,10 @@ var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
label: "[AST_Label] a label definition"
|
label: "[AST_Label] a label definition"
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.label.equals(node.label)
|
||||||
|
&& this.body.equals(node.body);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -417,6 +456,10 @@ var AST_DWLoop = DEFNODE("DWLoop", "condition", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
condition: "[AST_Node] the loop condition. Should not be instanceof AST_Statement"
|
condition: "[AST_Node] the loop condition. Should not be instanceof AST_Statement"
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.body.equals(node.body)
|
||||||
|
&& this.condition.equals(node.condition);
|
||||||
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
if (this.TYPE == "DWLoop") throw new Error("should not instantiate AST_DWLoop");
|
if (this.TYPE == "DWLoop") throw new Error("should not instantiate AST_DWLoop");
|
||||||
must_be_expression(this, "condition");
|
must_be_expression(this, "condition");
|
||||||
@@ -431,7 +474,7 @@ var AST_Do = DEFNODE("Do", null, {
|
|||||||
node.body.walk(visitor);
|
node.body.walk(visitor);
|
||||||
node.condition.walk(visitor);
|
node.condition.walk(visitor);
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
}, AST_DWLoop);
|
}, AST_DWLoop);
|
||||||
|
|
||||||
var AST_While = DEFNODE("While", null, {
|
var AST_While = DEFNODE("While", null, {
|
||||||
@@ -442,7 +485,7 @@ var AST_While = DEFNODE("While", null, {
|
|||||||
node.condition.walk(visitor);
|
node.condition.walk(visitor);
|
||||||
node.body.walk(visitor);
|
node.body.walk(visitor);
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
}, AST_DWLoop);
|
}, AST_DWLoop);
|
||||||
|
|
||||||
var AST_For = DEFNODE("For", "init condition step", {
|
var AST_For = DEFNODE("For", "init condition step", {
|
||||||
@@ -452,6 +495,12 @@ var AST_For = DEFNODE("For", "init condition step", {
|
|||||||
condition: "[AST_Node?] the `for` termination clause, or null if empty",
|
condition: "[AST_Node?] the `for` termination clause, or null if empty",
|
||||||
step: "[AST_Node?] the `for` update clause, or null if empty"
|
step: "[AST_Node?] the `for` update clause, or null if empty"
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return prop_equals(this.init, node.init)
|
||||||
|
&& prop_equals(this.condition, node.condition)
|
||||||
|
&& prop_equals(this.step, node.step)
|
||||||
|
&& this.body.equals(node.body);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -479,6 +528,11 @@ var AST_ForEnumeration = DEFNODE("ForEnumeration", "init object", {
|
|||||||
init: "[AST_Node] the assignment target during iteration",
|
init: "[AST_Node] the assignment target during iteration",
|
||||||
object: "[AST_Node] the object to iterate over"
|
object: "[AST_Node] the object to iterate over"
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.init.equals(node.init)
|
||||||
|
&& this.object.equals(node.object)
|
||||||
|
&& this.body.equals(node.body);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -519,6 +573,10 @@ var AST_With = DEFNODE("With", "expression", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
expression: "[AST_Node] the `with` expression"
|
expression: "[AST_Node] the `with` expression"
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.expression.equals(node.expression)
|
||||||
|
&& this.body.equals(node.body);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -534,7 +592,7 @@ var AST_With = DEFNODE("With", "expression", {
|
|||||||
/* -----[ scope and functions ]----- */
|
/* -----[ scope and functions ]----- */
|
||||||
|
|
||||||
var AST_Scope = DEFNODE("Scope", "fn_defs may_call_this uses_eval uses_with", {
|
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: {
|
$propdoc: {
|
||||||
uses_eval: "[boolean/S] tells whether this scope contains a direct call to the global `eval`",
|
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",
|
uses_with: "[boolean/S] tells whether this scope uses the `with` statement",
|
||||||
@@ -592,6 +650,10 @@ var AST_Toplevel = DEFNODE("Toplevel", "globals", {
|
|||||||
}
|
}
|
||||||
}, AST_Scope);
|
}, 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", {
|
var AST_Lambda = DEFNODE("Lambda", "argnames length_read rest safe_ids uses_arguments", {
|
||||||
$documentation: "Base class for functions",
|
$documentation: "Base class for functions",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
@@ -617,6 +679,13 @@ var AST_Lambda = DEFNODE("Lambda", "argnames length_read rest safe_ids uses_argu
|
|||||||
});
|
});
|
||||||
if (this.rest) this.rest.walk(tw);
|
if (this.rest) this.rest.walk(tw);
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return prop_equals(this.rest, node.rest)
|
||||||
|
&& prop_equals(this.name, node.name)
|
||||||
|
&& prop_equals(this.value, node.value)
|
||||||
|
&& all_equals(this.argnames, node.argnames)
|
||||||
|
&& all_equals(this.body, node.body);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -827,6 +896,11 @@ var AST_Class = DEFNODE("Class", "extends name properties", {
|
|||||||
extends: "[AST_Node?] the super class, or null if not specified",
|
extends: "[AST_Node?] the super class, or null if not specified",
|
||||||
properties: "[AST_ClassProperty*] array of class properties",
|
properties: "[AST_ClassProperty*] array of class properties",
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return prop_equals(this.name, node.name)
|
||||||
|
&& prop_equals(this.extends, node.extends)
|
||||||
|
&& all_equals(this.properties, node.properties);
|
||||||
|
},
|
||||||
resolve: function(def_class) {
|
resolve: function(def_class) {
|
||||||
return def_class ? this : this.parent_scope.resolve();
|
return def_class ? this : this.parent_scope.resolve();
|
||||||
},
|
},
|
||||||
@@ -874,11 +948,17 @@ var AST_ClassExpression = DEFNODE("ClassExpression", null, {
|
|||||||
var AST_ClassProperty = DEFNODE("ClassProperty", "key private static value", {
|
var AST_ClassProperty = DEFNODE("ClassProperty", "key private static value", {
|
||||||
$documentation: "Base class for `class` properties",
|
$documentation: "Base class for `class` properties",
|
||||||
$propdoc: {
|
$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",
|
private: "[boolean] whether this is a private property",
|
||||||
static: "[boolean] whether this is a static 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)",
|
value: "[AST_Node?] property value (AST_Accessor for getters/setters, AST_LambdaExpression for methods, null if not specified for fields)",
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return !this.private == !node.private
|
||||||
|
&& !this.static == !node.static
|
||||||
|
&& prop_equals(this.key, node.key)
|
||||||
|
&& prop_equals(this.value, node.value);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -888,7 +968,9 @@ var AST_ClassProperty = DEFNODE("ClassProperty", "key private static value", {
|
|||||||
},
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
if (this.TYPE == "ClassProperty") throw new Error("should not instantiate AST_ClassProperty");
|
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");
|
if (!(this.key instanceof AST_Node)) throw new Error("key must be string or AST_Node");
|
||||||
must_be_expression(this, "key");
|
must_be_expression(this, "key");
|
||||||
}
|
}
|
||||||
@@ -928,6 +1010,17 @@ var AST_ClassMethod = DEFNODE("ClassMethod", null, {
|
|||||||
},
|
},
|
||||||
}, AST_ClassProperty);
|
}, 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 ]----- */
|
/* -----[ JUMPS ]----- */
|
||||||
|
|
||||||
var AST_Jump = DEFNODE("Jump", null, {
|
var AST_Jump = DEFNODE("Jump", null, {
|
||||||
@@ -942,6 +1035,9 @@ var AST_Exit = DEFNODE("Exit", "value", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
value: "[AST_Node?] the value returned or thrown by this statement; could be null for AST_Return"
|
value: "[AST_Node?] the value returned or thrown by this statement; could be null for AST_Return"
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return prop_equals(this.value, node.value);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -972,6 +1068,9 @@ var AST_LoopControl = DEFNODE("LoopControl", "label", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
label: "[AST_LabelRef?] the label, or null if none",
|
label: "[AST_LabelRef?] the label, or null if none",
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return prop_equals(this.label, node.label);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1002,6 +1101,11 @@ var AST_If = DEFNODE("If", "condition alternative", {
|
|||||||
condition: "[AST_Node] the `if` condition",
|
condition: "[AST_Node] the `if` condition",
|
||||||
alternative: "[AST_Statement?] the `else` part, or null if not present"
|
alternative: "[AST_Statement?] the `else` part, or null if not present"
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.body.equals(node.body)
|
||||||
|
&& this.condition.equals(node.condition)
|
||||||
|
&& prop_equals(this.alternative, node.alternative);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1025,6 +1129,10 @@ var AST_Switch = DEFNODE("Switch", "expression", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
expression: "[AST_Node] the `switch` “discriminant”"
|
expression: "[AST_Node] the `switch` “discriminant”"
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.expression.equals(node.expression)
|
||||||
|
&& all_equals(this.body, node.body);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1056,6 +1164,10 @@ var AST_Case = DEFNODE("Case", "expression", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
expression: "[AST_Node] the `case` expression"
|
expression: "[AST_Node] the `case` expression"
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.expression.equals(node.expression)
|
||||||
|
&& all_equals(this.body, node.body);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1076,6 +1188,11 @@ var AST_Try = DEFNODE("Try", "bcatch bfinally", {
|
|||||||
bcatch: "[AST_Catch?] the catch block, or null if not present",
|
bcatch: "[AST_Catch?] the catch block, or null if not present",
|
||||||
bfinally: "[AST_Finally?] the finally block, or null if not present"
|
bfinally: "[AST_Finally?] the finally block, or null if not present"
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return all_equals(this.body, node.body)
|
||||||
|
&& prop_equals(this.bcatch, node.bcatch)
|
||||||
|
&& prop_equals(this.bfinally, node.bfinally);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1099,6 +1216,10 @@ var AST_Catch = DEFNODE("Catch", "argname", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
argname: "[(AST_Destructured|AST_SymbolCatch)?] symbol for the exception, or null if not present",
|
argname: "[(AST_Destructured|AST_SymbolCatch)?] symbol for the exception, or null if not present",
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return prop_equals(this.argname, node.argname)
|
||||||
|
&& all_equals(this.body, node.body);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1124,6 +1245,9 @@ var AST_Definitions = DEFNODE("Definitions", "definitions", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
definitions: "[AST_VarDef*] array of variable definitions"
|
definitions: "[AST_VarDef*] array of variable definitions"
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return all_equals(this.definitions, node.definitions);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1180,6 +1304,10 @@ var AST_VarDef = DEFNODE("VarDef", "name value", {
|
|||||||
name: "[AST_Destructured|AST_SymbolVar] name of the variable",
|
name: "[AST_Destructured|AST_SymbolVar] name of the variable",
|
||||||
value: "[AST_Node?] initializer, or null of there's no initializer",
|
value: "[AST_Node?] initializer, or null of there's no initializer",
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.name.equals(node.name)
|
||||||
|
&& prop_equals(this.value, node.value);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1199,6 +1327,9 @@ var AST_ExportDeclaration = DEFNODE("ExportDeclaration", "body", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
body: "[AST_DefClass|AST_Definitions|AST_LambdaDefinition] the statement to export",
|
body: "[AST_DefClass|AST_Definitions|AST_LambdaDefinition] the statement to export",
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.body.equals(node.body);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1219,6 +1350,9 @@ var AST_ExportDefault = DEFNODE("ExportDefault", "body", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
body: "[AST_Node] the default export",
|
body: "[AST_Node] the default export",
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.body.equals(node.body);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1232,29 +1366,29 @@ var AST_ExportDefault = DEFNODE("ExportDefault", "body", {
|
|||||||
},
|
},
|
||||||
}, AST_Statement);
|
}, AST_Statement);
|
||||||
|
|
||||||
var AST_ExportForeign = DEFNODE("ExportForeign", "aliases keys path quote", {
|
var AST_ExportForeign = DEFNODE("ExportForeign", "aliases keys path", {
|
||||||
$documentation: "An `export ... from '...'` statement",
|
$documentation: "An `export ... from '...'` statement",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
aliases: "[string*] array of aliases to export",
|
aliases: "[AST_String*] array of aliases to export",
|
||||||
keys: "[string*] array of keys to import",
|
keys: "[AST_String*] array of keys to import",
|
||||||
path: "[string] the path to import module",
|
path: "[AST_String] the path to import module",
|
||||||
quote: "[string?] the original quote character",
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.path.equals(node.path)
|
||||||
|
&& all_equals(this.aliases, node.aliases)
|
||||||
|
&& all_equals(this.keys, node.keys);
|
||||||
},
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
if (this.aliases.length != this.keys.length) {
|
if (this.aliases.length != this.keys.length) {
|
||||||
throw new Error("aliases:key length mismatch: " + this.aliases.length + " != " + this.keys.length);
|
throw new Error("aliases:key length mismatch: " + this.aliases.length + " != " + this.keys.length);
|
||||||
}
|
}
|
||||||
this.aliases.forEach(function(name) {
|
this.aliases.forEach(function(name) {
|
||||||
if (typeof name != "string") throw new Error("aliases must contain string");
|
if (!(name instanceof AST_String)) throw new Error("aliases must contain AST_String");
|
||||||
});
|
});
|
||||||
this.keys.forEach(function(name) {
|
this.keys.forEach(function(name) {
|
||||||
if (typeof name != "string") throw new Error("keys must contain string");
|
if (!(name instanceof AST_String)) throw new Error("keys must contain AST_String");
|
||||||
});
|
});
|
||||||
if (typeof this.path != "string") throw new Error("path must be string");
|
if (!(this.path instanceof AST_String)) throw new Error("path must be AST_String");
|
||||||
if (this.quote != null) {
|
|
||||||
if (typeof this.quote != "string") throw new Error("quote must be string");
|
|
||||||
if (!/^["']$/.test(this.quote)) throw new Error("invalid quote: " + this.quote);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
}, AST_Statement);
|
}, AST_Statement);
|
||||||
|
|
||||||
@@ -1263,6 +1397,9 @@ var AST_ExportReferences = DEFNODE("ExportReferences", "properties", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
properties: "[AST_SymbolExport*] array of aliases to export",
|
properties: "[AST_SymbolExport*] array of aliases to export",
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return all_equals(this.properties, node.properties);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1278,14 +1415,20 @@ var AST_ExportReferences = DEFNODE("ExportReferences", "properties", {
|
|||||||
},
|
},
|
||||||
}, AST_Statement);
|
}, AST_Statement);
|
||||||
|
|
||||||
var AST_Import = DEFNODE("Import", "all default path properties quote", {
|
var AST_Import = DEFNODE("Import", "all default path properties", {
|
||||||
$documentation: "An `import` statement",
|
$documentation: "An `import` statement",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
all: "[AST_SymbolImport?] the imported namespace, or null if not specified",
|
all: "[AST_SymbolImport?] the imported namespace, or null if not specified",
|
||||||
default: "[AST_SymbolImport?] the alias for default `export`, or null if not specified",
|
default: "[AST_SymbolImport?] the alias for default `export`, or null if not specified",
|
||||||
path: "[string] the path to import module",
|
path: "[AST_String] the path to import module",
|
||||||
properties: "[(AST_SymbolImport*)?] array of aliases, or null if not specified",
|
properties: "[(AST_SymbolImport*)?] array of aliases, or null if not specified",
|
||||||
quote: "[string?] the original quote character",
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.path.equals(node.path)
|
||||||
|
&& prop_equals(this.all, node.all)
|
||||||
|
&& prop_equals(this.default, node.default)
|
||||||
|
&& !this.properties == !node.properties
|
||||||
|
&& (!this.properties || all_equals(this.properties, node.properties));
|
||||||
},
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
@@ -1304,16 +1447,12 @@ var AST_Import = DEFNODE("Import", "all default path properties quote", {
|
|||||||
}
|
}
|
||||||
if (this.default != null) {
|
if (this.default != null) {
|
||||||
if (!(this.default instanceof AST_SymbolImport)) throw new Error("default must be AST_SymbolImport");
|
if (!(this.default instanceof AST_SymbolImport)) throw new Error("default must be AST_SymbolImport");
|
||||||
if (this.default.key !== "") throw new Error("invalid default key: " + this.default.key);
|
if (this.default.key.value !== "") throw new Error("invalid default key: " + this.default.key.value);
|
||||||
}
|
}
|
||||||
if (typeof this.path != "string") throw new Error("path must be string");
|
if (!(this.path instanceof AST_String)) throw new Error("path must be AST_String");
|
||||||
if (this.properties != null) this.properties.forEach(function(node) {
|
if (this.properties != null) this.properties.forEach(function(node) {
|
||||||
if (!(node instanceof AST_SymbolImport)) throw new Error("properties must contain AST_SymbolImport");
|
if (!(node instanceof AST_SymbolImport)) throw new Error("properties must contain AST_SymbolImport");
|
||||||
});
|
});
|
||||||
if (this.quote != null) {
|
|
||||||
if (typeof this.quote != "string") throw new Error("quote must be string");
|
|
||||||
if (!/^["']$/.test(this.quote)) throw new Error("invalid quote: " + this.quote);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
}, AST_Statement);
|
}, AST_Statement);
|
||||||
|
|
||||||
@@ -1323,6 +1462,10 @@ var AST_DefaultValue = DEFNODE("DefaultValue", "name value", {
|
|||||||
name: "[AST_Destructured|AST_SymbolDeclaration] name of the variable",
|
name: "[AST_Destructured|AST_SymbolDeclaration] name of the variable",
|
||||||
value: "[AST_Node] value to assign if variable is `undefined`",
|
value: "[AST_Node] value to assign if variable is `undefined`",
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.name.equals(node.name)
|
||||||
|
&& this.value.equals(node.value);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1350,6 +1493,11 @@ var AST_Call = DEFNODE("Call", "args expression optional pure terminal", {
|
|||||||
pure: "[boolean/S] marker for side-effect-free call expression",
|
pure: "[boolean/S] marker for side-effect-free call expression",
|
||||||
terminal: "[boolean] whether the chain has ended",
|
terminal: "[boolean] whether the chain has ended",
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return !this.optional == !node.optional
|
||||||
|
&& this.expression.equals(node.expression)
|
||||||
|
&& all_equals(this.args, node.args);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1378,6 +1526,9 @@ var AST_Sequence = DEFNODE("Sequence", "expressions", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
expressions: "[AST_Node*] array of expressions (at least two)"
|
expressions: "[AST_Node*] array of expressions (at least two)"
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return all_equals(this.expressions, node.expressions);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1405,6 +1556,11 @@ var AST_PropAccess = DEFNODE("PropAccess", "expression optional property termina
|
|||||||
property: "[AST_Node|string] the property to access. For AST_Dot this is always a plain string, while for AST_Sub it's an arbitrary AST_Node",
|
property: "[AST_Node|string] the property to access. For AST_Dot this is always a plain string, while for AST_Sub it's an arbitrary AST_Node",
|
||||||
terminal: "[boolean] whether the chain has ended",
|
terminal: "[boolean] whether the chain has ended",
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return !this.optional == !node.optional
|
||||||
|
&& prop_equals(this.property, node.property)
|
||||||
|
&& this.expression.equals(node.expression);
|
||||||
|
},
|
||||||
get_property: function() {
|
get_property: function() {
|
||||||
var p = this.property;
|
var p = this.property;
|
||||||
if (p instanceof AST_Constant) return p.value;
|
if (p instanceof AST_Constant) return p.value;
|
||||||
@@ -1449,6 +1605,9 @@ var AST_Spread = DEFNODE("Spread", "expression", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
expression: "[AST_Node] expression to be expanded",
|
expression: "[AST_Node] expression to be expanded",
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.expression.equals(node.expression);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1466,6 +1625,10 @@ var AST_Unary = DEFNODE("Unary", "operator expression", {
|
|||||||
operator: "[string] the operator",
|
operator: "[string] the operator",
|
||||||
expression: "[AST_Node] expression that this unary operator applies to"
|
expression: "[AST_Node] expression that this unary operator applies to"
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.operator == node.operator
|
||||||
|
&& this.expression.equals(node.expression);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1494,6 +1657,11 @@ var AST_Binary = DEFNODE("Binary", "operator left right", {
|
|||||||
operator: "[string] the operator",
|
operator: "[string] the operator",
|
||||||
right: "[AST_Node] right-hand side expression"
|
right: "[AST_Node] right-hand side expression"
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.operator == node.operator
|
||||||
|
&& this.left.equals(node.left)
|
||||||
|
&& this.right.equals(node.right);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1515,6 +1683,11 @@ var AST_Conditional = DEFNODE("Conditional", "condition consequent alternative",
|
|||||||
consequent: "[AST_Node]",
|
consequent: "[AST_Node]",
|
||||||
alternative: "[AST_Node]"
|
alternative: "[AST_Node]"
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.condition.equals(node.condition)
|
||||||
|
&& this.consequent.equals(node.consequent)
|
||||||
|
&& this.alternative.equals(node.alternative);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1556,6 +1729,9 @@ var AST_Await = DEFNODE("Await", "expression", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
expression: "[AST_Node] expression with Promise to resolve on",
|
expression: "[AST_Node] expression with Promise to resolve on",
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.expression.equals(node.expression);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1573,6 +1749,10 @@ var AST_Yield = DEFNODE("Yield", "expression nested", {
|
|||||||
expression: "[AST_Node?] return value for iterator, or null if undefined",
|
expression: "[AST_Node?] return value for iterator, or null if undefined",
|
||||||
nested: "[boolean] whether to iterate over expression as generator",
|
nested: "[boolean] whether to iterate over expression as generator",
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return !this.nested == !node.nested
|
||||||
|
&& prop_equals(this.expression, node.expression);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1595,6 +1775,9 @@ var AST_Array = DEFNODE("Array", "elements", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
elements: "[AST_Node*] array of elements"
|
elements: "[AST_Node*] array of elements"
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return all_equals(this.elements, node.elements);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1637,6 +1820,10 @@ var AST_DestructuredArray = DEFNODE("DestructuredArray", "elements", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
elements: "[(AST_DefaultValue|AST_Destructured|AST_SymbolDeclaration|AST_SymbolRef)*] array of elements",
|
elements: "[(AST_DefaultValue|AST_Destructured|AST_SymbolDeclaration|AST_SymbolRef)*] array of elements",
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return prop_equals(this.rest, node.rest)
|
||||||
|
&& all_equals(this.elements, node.elements);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1654,6 +1841,10 @@ var AST_DestructuredKeyVal = DEFNODE("DestructuredKeyVal", "key value", {
|
|||||||
key: "[string|AST_Node] property name. For computed property this is an AST_Node.",
|
key: "[string|AST_Node] property name. For computed property this is an AST_Node.",
|
||||||
value: "[AST_DefaultValue|AST_Destructured|AST_SymbolDeclaration|AST_SymbolRef] property value",
|
value: "[AST_DefaultValue|AST_Destructured|AST_SymbolDeclaration|AST_SymbolRef] property value",
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return prop_equals(this.key, node.key)
|
||||||
|
&& this.value.equals(node.value);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1675,6 +1866,10 @@ var AST_DestructuredObject = DEFNODE("DestructuredObject", "properties", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
properties: "[AST_DestructuredKeyVal*] array of properties",
|
properties: "[AST_DestructuredKeyVal*] array of properties",
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return prop_equals(this.rest, node.rest)
|
||||||
|
&& all_equals(this.properties, node.properties);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1696,6 +1891,9 @@ var AST_Object = DEFNODE("Object", "properties", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
properties: "[(AST_ObjectProperty|AST_Spread)*] array of properties"
|
properties: "[(AST_ObjectProperty|AST_Spread)*] array of properties"
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return all_equals(this.properties, node.properties);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1719,6 +1917,10 @@ var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", {
|
|||||||
key: "[string|AST_Node] property name. For computed property this is an AST_Node.",
|
key: "[string|AST_Node] property name. For computed property this is an AST_Node.",
|
||||||
value: "[AST_Node] property value. For getters and setters this is an AST_Accessor.",
|
value: "[AST_Node] property value. For getters and setters this is an AST_Accessor.",
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return prop_equals(this.key, node.key)
|
||||||
|
&& this.value.equals(node.value);
|
||||||
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
@@ -1773,6 +1975,9 @@ var AST_Symbol = DEFNODE("Symbol", "scope name thedef", {
|
|||||||
scope: "[AST_Scope/S] the current scope (not necessarily the definition scope)",
|
scope: "[AST_Scope/S] the current scope (not necessarily the definition scope)",
|
||||||
thedef: "[SymbolDef/S] the definition of this symbol"
|
thedef: "[SymbolDef/S] the definition of this symbol"
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.thedef ? this.thedef === node.thedef : this.name == node.name;
|
||||||
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
if (this.TYPE == "Symbol") throw new Error("should not instantiate AST_Symbol");
|
if (this.TYPE == "Symbol") throw new Error("should not instantiate AST_Symbol");
|
||||||
if (typeof this.name != "string") throw new Error("name must be string");
|
if (typeof this.name != "string") throw new Error("name must be string");
|
||||||
@@ -1790,10 +1995,14 @@ var AST_SymbolConst = DEFNODE("SymbolConst", null, {
|
|||||||
var AST_SymbolImport = DEFNODE("SymbolImport", "key", {
|
var AST_SymbolImport = DEFNODE("SymbolImport", "key", {
|
||||||
$documentation: "Symbol defined by an `import` statement",
|
$documentation: "Symbol defined by an `import` statement",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
key: "[string] the original `export` name",
|
key: "[AST_String] the original `export` name",
|
||||||
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.name == node.name
|
||||||
|
&& this.key.equals(node.key);
|
||||||
},
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
if (typeof this.key != "string") throw new Error("key must be string");
|
if (!(this.key instanceof AST_String)) throw new Error("key must be AST_String");
|
||||||
},
|
},
|
||||||
}, AST_SymbolConst);
|
}, AST_SymbolConst);
|
||||||
|
|
||||||
@@ -1847,10 +2056,14 @@ var AST_SymbolRef = DEFNODE("SymbolRef", "fixed in_arg redef", {
|
|||||||
var AST_SymbolExport = DEFNODE("SymbolExport", "alias", {
|
var AST_SymbolExport = DEFNODE("SymbolExport", "alias", {
|
||||||
$documentation: "Reference in an `export` statement",
|
$documentation: "Reference in an `export` statement",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
alias: "[string] the `export` alias",
|
alias: "[AST_String] the `export` alias",
|
||||||
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.name == node.name
|
||||||
|
&& this.alias.equals(node.alias);
|
||||||
},
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
if (typeof this.alias != "string") throw new Error("alias must be string");
|
if (!(this.alias instanceof AST_String)) throw new Error("alias must be AST_String");
|
||||||
},
|
},
|
||||||
}, AST_SymbolRef);
|
}, AST_SymbolRef);
|
||||||
|
|
||||||
@@ -1860,6 +2073,7 @@ var AST_LabelRef = DEFNODE("LabelRef", null, {
|
|||||||
|
|
||||||
var AST_ObjectIdentity = DEFNODE("ObjectIdentity", null, {
|
var AST_ObjectIdentity = DEFNODE("ObjectIdentity", null, {
|
||||||
$documentation: "Base class for `super` & `this`",
|
$documentation: "Base class for `super` & `this`",
|
||||||
|
_equals: return_true,
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
if (this.TYPE == "ObjectIdentity") throw new Error("should not instantiate AST_ObjectIdentity");
|
if (this.TYPE == "ObjectIdentity") throw new Error("should not instantiate AST_ObjectIdentity");
|
||||||
},
|
},
|
||||||
@@ -1894,7 +2108,12 @@ var AST_Template = DEFNODE("Template", "expressions strings tag", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
expressions: "[AST_Node*] the placeholder expressions",
|
expressions: "[AST_Node*] the placeholder expressions",
|
||||||
strings: "[string*] the raw text segments",
|
strings: "[string*] the raw text segments",
|
||||||
tag: "[AST_Node] tag function, or null if absent",
|
tag: "[AST_Node?] tag function, or null if absent",
|
||||||
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return prop_equals(this.tag, node.tag)
|
||||||
|
&& list_equals(this.strings, node.strings)
|
||||||
|
&& all_equals(this.expressions, node.expressions);
|
||||||
},
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
@@ -1919,6 +2138,9 @@ var AST_Template = DEFNODE("Template", "expressions strings tag", {
|
|||||||
|
|
||||||
var AST_Constant = DEFNODE("Constant", null, {
|
var AST_Constant = DEFNODE("Constant", null, {
|
||||||
$documentation: "Base class for all constants",
|
$documentation: "Base class for all constants",
|
||||||
|
_equals: function(node) {
|
||||||
|
return this.value === node.value;
|
||||||
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
if (this.TYPE == "Constant") throw new Error("should not instantiate AST_Constant");
|
if (this.TYPE == "Constant") throw new Error("should not instantiate AST_Constant");
|
||||||
},
|
},
|
||||||
@@ -1967,6 +2189,9 @@ var AST_RegExp = DEFNODE("RegExp", "value", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
value: "[RegExp] the actual regexp"
|
value: "[RegExp] the actual regexp"
|
||||||
},
|
},
|
||||||
|
_equals: function(node) {
|
||||||
|
return "" + this.value == "" + node.value;
|
||||||
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
if (!(this.value instanceof RegExp)) throw new Error("value must be RegExp");
|
if (!(this.value instanceof RegExp)) throw new Error("value must be RegExp");
|
||||||
},
|
},
|
||||||
@@ -1974,6 +2199,7 @@ var AST_RegExp = DEFNODE("RegExp", "value", {
|
|||||||
|
|
||||||
var AST_Atom = DEFNODE("Atom", null, {
|
var AST_Atom = DEFNODE("Atom", null, {
|
||||||
$documentation: "Base class for atoms",
|
$documentation: "Base class for atoms",
|
||||||
|
_equals: return_true,
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
if (this.TYPE == "Atom") throw new Error("should not instantiate AST_Atom");
|
if (this.TYPE == "Atom") throw new Error("should not instantiate AST_Atom");
|
||||||
},
|
},
|
||||||
|
|||||||
797
lib/compress.js
797
lib/compress.js
File diff suppressed because it is too large
Load Diff
@@ -192,6 +192,19 @@
|
|||||||
value: from_moz(M.value),
|
value: from_moz(M.value),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
StaticBlock: function(M) {
|
||||||
|
var start = my_start_token(M);
|
||||||
|
var end = my_end_token(M);
|
||||||
|
return new AST_ClassInit({
|
||||||
|
start: start,
|
||||||
|
end: end,
|
||||||
|
value: new AST_ClassInitBlock({
|
||||||
|
start: start,
|
||||||
|
end: end,
|
||||||
|
body: normalize_directives(M.body.map(from_moz)),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
},
|
||||||
ForOfStatement: function(M) {
|
ForOfStatement: function(M) {
|
||||||
return new (M.await ? AST_ForAwaitOf : AST_ForOf)({
|
return new (M.await ? AST_ForAwaitOf : AST_ForOf)({
|
||||||
start: my_start_token(M),
|
start: my_start_token(M),
|
||||||
@@ -303,13 +316,22 @@
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
ExportAllDeclaration: function(M) {
|
ExportAllDeclaration: function(M) {
|
||||||
var alias = M.exported ? read_name(M.exported) : "*";
|
var start = my_start_token(M);
|
||||||
|
var end = my_end_token(M);
|
||||||
return new AST_ExportForeign({
|
return new AST_ExportForeign({
|
||||||
start: my_start_token(M),
|
start: start,
|
||||||
end: my_end_token(M),
|
end: end,
|
||||||
aliases: [ alias ],
|
aliases: [ M.exported ? from_moz_alias(M.exported) : new AST_String({
|
||||||
keys: [ "*" ],
|
start: start,
|
||||||
path: M.source.value,
|
value: "*",
|
||||||
|
end: end,
|
||||||
|
}) ],
|
||||||
|
keys: [ new AST_String({
|
||||||
|
start: start,
|
||||||
|
value: "*",
|
||||||
|
end: end,
|
||||||
|
}) ],
|
||||||
|
path: from_moz(M.source),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
ExportDefaultDeclaration: function(M) {
|
ExportDefaultDeclaration: function(M) {
|
||||||
@@ -346,15 +368,15 @@
|
|||||||
if (M.source) {
|
if (M.source) {
|
||||||
var aliases = [], keys = [];
|
var aliases = [], keys = [];
|
||||||
M.specifiers.forEach(function(prop) {
|
M.specifiers.forEach(function(prop) {
|
||||||
aliases.push(read_name(prop.exported));
|
aliases.push(from_moz_alias(prop.exported));
|
||||||
keys.push(read_name(prop.local));
|
keys.push(from_moz_alias(prop.local));
|
||||||
});
|
});
|
||||||
return new AST_ExportForeign({
|
return new AST_ExportForeign({
|
||||||
start: my_start_token(M),
|
start: my_start_token(M),
|
||||||
end: my_end_token(M),
|
end: my_end_token(M),
|
||||||
aliases: aliases,
|
aliases: aliases,
|
||||||
keys: keys,
|
keys: keys,
|
||||||
path: M.source.value,
|
path: from_moz(M.source),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return new AST_ExportReferences({
|
return new AST_ExportReferences({
|
||||||
@@ -362,38 +384,48 @@
|
|||||||
end: my_end_token(M),
|
end: my_end_token(M),
|
||||||
properties: M.specifiers.map(function(prop) {
|
properties: M.specifiers.map(function(prop) {
|
||||||
var sym = new AST_SymbolExport(from_moz(prop.local));
|
var sym = new AST_SymbolExport(from_moz(prop.local));
|
||||||
sym.alias = read_name(prop.exported);
|
sym.alias = from_moz_alias(prop.exported);
|
||||||
return sym;
|
return sym;
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
ImportDeclaration: function(M) {
|
ImportDeclaration: function(M) {
|
||||||
|
var start = my_start_token(M);
|
||||||
|
var end = my_end_token(M);
|
||||||
var all = null, def = null, props = null;
|
var all = null, def = null, props = null;
|
||||||
M.specifiers.forEach(function(prop) {
|
M.specifiers.forEach(function(prop) {
|
||||||
var sym = new AST_SymbolImport(from_moz(prop.local));
|
var sym = new AST_SymbolImport(from_moz(prop.local));
|
||||||
switch (prop.type) {
|
switch (prop.type) {
|
||||||
case "ImportDefaultSpecifier":
|
case "ImportDefaultSpecifier":
|
||||||
def = sym;
|
def = sym;
|
||||||
def.key = "";
|
def.key = new AST_String({
|
||||||
|
start: start,
|
||||||
|
value: "",
|
||||||
|
end: end,
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
case "ImportNamespaceSpecifier":
|
case "ImportNamespaceSpecifier":
|
||||||
all = sym;
|
all = sym;
|
||||||
all.key = "*";
|
all.key = new AST_String({
|
||||||
|
start: start,
|
||||||
|
value: "*",
|
||||||
|
end: end,
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
sym.key = prop.imported.name || syn.name;
|
sym.key = from_moz_alias(prop.imported);
|
||||||
if (!props) props = [];
|
if (!props) props = [];
|
||||||
props.push(sym);
|
props.push(sym);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return new AST_Import({
|
return new AST_Import({
|
||||||
start: my_start_token(M),
|
start: start,
|
||||||
end: my_end_token(M),
|
end: end,
|
||||||
all: all,
|
all: all,
|
||||||
default: def,
|
default: def,
|
||||||
properties: props,
|
properties: props,
|
||||||
path: M.source.value,
|
path: from_moz(M.source),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
ImportExpression: function(M) {
|
ImportExpression: function(M) {
|
||||||
@@ -714,6 +746,10 @@
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
def_to_moz(AST_ClassInit, function To_Moz_StaticBlock(M) {
|
||||||
|
return to_moz_scope("StaticBlock", M.value);
|
||||||
|
});
|
||||||
|
|
||||||
function To_Moz_ForOfStatement(is_await) {
|
function To_Moz_ForOfStatement(is_await) {
|
||||||
return function(M) {
|
return function(M) {
|
||||||
return {
|
return {
|
||||||
@@ -780,38 +816,26 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
def_to_moz(AST_ExportForeign, function To_Moz_ExportAllDeclaration_ExportNamedDeclaration(M) {
|
def_to_moz(AST_ExportForeign, function To_Moz_ExportAllDeclaration_ExportNamedDeclaration(M) {
|
||||||
if (M.keys[0] == "*") return {
|
if (M.keys[0].value == "*") return {
|
||||||
type: "ExportAllDeclaration",
|
type: "ExportAllDeclaration",
|
||||||
exported: M.aliases[0] == "*" ? null : {
|
exported: M.aliases[0].value == "*" ? null : to_moz_alias(M.aliases[0]),
|
||||||
type: "Identifier",
|
source: to_moz(M.path),
|
||||||
name: M.aliases[0],
|
|
||||||
},
|
|
||||||
source: {
|
|
||||||
type: "Literal",
|
|
||||||
value: M.path,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
var specifiers = [];
|
var specifiers = [];
|
||||||
for (var i = 0; i < M.aliases.length; i++) {
|
for (var i = 0; i < M.aliases.length; i++) {
|
||||||
specifiers.push({
|
specifiers.push(set_moz_loc({
|
||||||
|
start: M.keys[i].start,
|
||||||
|
end: M.aliases[i].end,
|
||||||
|
}, {
|
||||||
type: "ExportSpecifier",
|
type: "ExportSpecifier",
|
||||||
exported: {
|
local: to_moz_alias(M.keys[i]),
|
||||||
type: "Identifier",
|
exported: to_moz_alias(M.aliases[i]),
|
||||||
name: M.aliases[i],
|
}));
|
||||||
},
|
|
||||||
local: {
|
|
||||||
type: "Identifier",
|
|
||||||
name: M.keys[i],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
type: "ExportNamedDeclaration",
|
type: "ExportNamedDeclaration",
|
||||||
specifiers: specifiers,
|
specifiers: specifiers,
|
||||||
source: {
|
source: to_moz(M.path),
|
||||||
type: "Literal",
|
|
||||||
value: M.path,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -819,44 +843,41 @@
|
|||||||
return {
|
return {
|
||||||
type: "ExportNamedDeclaration",
|
type: "ExportNamedDeclaration",
|
||||||
specifiers: M.properties.map(function(prop) {
|
specifiers: M.properties.map(function(prop) {
|
||||||
return {
|
return set_moz_loc({
|
||||||
|
start: prop.start,
|
||||||
|
end: prop.alias.end,
|
||||||
|
}, {
|
||||||
type: "ExportSpecifier",
|
type: "ExportSpecifier",
|
||||||
local: to_moz(prop),
|
local: to_moz(prop),
|
||||||
exported: {
|
exported: to_moz_alias(prop.alias),
|
||||||
type: "Identifier",
|
});
|
||||||
name: prop.alias,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
def_to_moz(AST_Import, function To_Moz_ImportDeclaration(M) {
|
def_to_moz(AST_Import, function To_Moz_ImportDeclaration(M) {
|
||||||
var specifiers = M.properties ? M.properties.map(function(prop) {
|
var specifiers = M.properties ? M.properties.map(function(prop) {
|
||||||
return {
|
return set_moz_loc({
|
||||||
|
start: prop.key.start,
|
||||||
|
end: prop.end,
|
||||||
|
}, {
|
||||||
type: "ImportSpecifier",
|
type: "ImportSpecifier",
|
||||||
local: to_moz(prop),
|
local: to_moz(prop),
|
||||||
imported: {
|
imported: to_moz_alias(prop.key),
|
||||||
type: "Identifier",
|
});
|
||||||
name: prop.key,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}) : [];
|
}) : [];
|
||||||
if (M.all) specifiers.unshift({
|
if (M.all) specifiers.unshift(set_moz_loc(M.all, {
|
||||||
type: "ImportNamespaceSpecifier",
|
type: "ImportNamespaceSpecifier",
|
||||||
local: to_moz(M.all),
|
local: to_moz(M.all),
|
||||||
});
|
}));
|
||||||
if (M.default) specifiers.unshift({
|
if (M.default) specifiers.unshift(set_moz_loc(M.default, {
|
||||||
type: "ImportDefaultSpecifier",
|
type: "ImportDefaultSpecifier",
|
||||||
local: to_moz(M.default),
|
local: to_moz(M.default),
|
||||||
});
|
}));
|
||||||
return {
|
return {
|
||||||
type: "ImportDeclaration",
|
type: "ImportDeclaration",
|
||||||
specifiers: specifiers,
|
specifiers: specifiers,
|
||||||
source: {
|
source: to_moz(M.path),
|
||||||
type: "Literal",
|
|
||||||
value: M.path,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1203,6 +1224,14 @@
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function from_moz_alias(moz) {
|
||||||
|
return new AST_String({
|
||||||
|
start: my_start_token(moz),
|
||||||
|
value: read_name(moz),
|
||||||
|
end: my_end_token(moz),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
AST_Node.from_mozilla_ast = function(node) {
|
AST_Node.from_mozilla_ast = function(node) {
|
||||||
var save_stack = FROM_MOZ_STACK;
|
var save_stack = FROM_MOZ_STACK;
|
||||||
FROM_MOZ_STACK = [];
|
FROM_MOZ_STACK = [];
|
||||||
@@ -1254,6 +1283,13 @@
|
|||||||
return node != null ? node.to_mozilla_ast() : null;
|
return node != null ? node.to_mozilla_ast() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function to_moz_alias(alias) {
|
||||||
|
return is_identifier_string(alias.value) ? set_moz_loc(alias, {
|
||||||
|
type: "Identifier",
|
||||||
|
name: alias.value,
|
||||||
|
}) : to_moz(alias);
|
||||||
|
}
|
||||||
|
|
||||||
function to_moz_block(node) {
|
function to_moz_block(node) {
|
||||||
return {
|
return {
|
||||||
type: "BlockStatement",
|
type: "BlockStatement",
|
||||||
|
|||||||
@@ -260,6 +260,15 @@ function OutputStream(options) {
|
|||||||
|
|
||||||
var require_semicolon = makePredicate("( [ + * / - , .");
|
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
|
var print = options.beautify
|
||||||
|| options.comments
|
|| options.comments
|
||||||
|| options.max_line_len
|
|| options.max_line_len
|
||||||
@@ -312,12 +321,7 @@ function OutputStream(options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (might_need_space) {
|
if (might_need_space) {
|
||||||
if (is_identifier_char(prev) && (is_identifier_char(ch) || ch == "\\")
|
if (require_space(prev, ch, str)) {
|
||||||
|| (ch == "/" && ch == prev)
|
|
||||||
|| ((ch == "+" || ch == "-") && ch == last)
|
|
||||||
|| str == "--" && last == "!"
|
|
||||||
|| str == "in" && prev == "/"
|
|
||||||
|| last == "--" && ch == ">") {
|
|
||||||
output += " ";
|
output += " ";
|
||||||
current_col++;
|
current_col++;
|
||||||
}
|
}
|
||||||
@@ -355,14 +359,7 @@ function OutputStream(options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (might_need_space) {
|
if (might_need_space) {
|
||||||
if (is_identifier_char(prev) && (is_identifier_char(ch) || ch == "\\")
|
if (require_space(prev, ch, str)) output += " ";
|
||||||
|| (ch == "/" && ch == prev)
|
|
||||||
|| ((ch == "+" || ch == "-") && ch == last)
|
|
||||||
|| str == "--" && last == "!"
|
|
||||||
|| str == "in" && prev == "/"
|
|
||||||
|| last == "--" && ch == ">") {
|
|
||||||
output += " ";
|
|
||||||
}
|
|
||||||
if (prev != "<" || str != "!") might_need_space = false;
|
if (prev != "<" || str != "!") might_need_space = false;
|
||||||
}
|
}
|
||||||
output += str;
|
output += str;
|
||||||
@@ -1064,6 +1061,14 @@ function OutputStream(options) {
|
|||||||
}
|
}
|
||||||
output.semicolon();
|
output.semicolon();
|
||||||
});
|
});
|
||||||
|
function print_alias(alias, output) {
|
||||||
|
var value = alias.value;
|
||||||
|
if (value == "*" || is_identifier_string(value)) {
|
||||||
|
output.print_name(value);
|
||||||
|
} else {
|
||||||
|
output.print_string(value, alias.quote);
|
||||||
|
}
|
||||||
|
}
|
||||||
DEFPRINT(AST_ExportForeign, function(output) {
|
DEFPRINT(AST_ExportForeign, function(output) {
|
||||||
var self = this;
|
var self = this;
|
||||||
output.print("export");
|
output.print("export");
|
||||||
@@ -1071,7 +1076,7 @@ function OutputStream(options) {
|
|||||||
var len = self.keys.length;
|
var len = self.keys.length;
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
print_braced_empty(self, output);
|
print_braced_empty(self, output);
|
||||||
} else if (self.keys[0] == "*") {
|
} else if (self.keys[0].value == "*") {
|
||||||
print_entry(0);
|
print_entry(0);
|
||||||
} else output.with_block(function() {
|
} else output.with_block(function() {
|
||||||
output.indent();
|
output.indent();
|
||||||
@@ -1087,18 +1092,18 @@ function OutputStream(options) {
|
|||||||
output.space();
|
output.space();
|
||||||
output.print("from");
|
output.print("from");
|
||||||
output.space();
|
output.space();
|
||||||
output.print_string(self.path, self.quote);
|
self.path.print(output);
|
||||||
output.semicolon();
|
output.semicolon();
|
||||||
|
|
||||||
function print_entry(index) {
|
function print_entry(index) {
|
||||||
var alias = self.aliases[index];
|
var alias = self.aliases[index];
|
||||||
var key = self.keys[index];
|
var key = self.keys[index];
|
||||||
output.print_name(key);
|
print_alias(key, output);
|
||||||
if (alias != key) {
|
if (alias.value != key.value) {
|
||||||
output.space();
|
output.space();
|
||||||
output.print("as");
|
output.print("as");
|
||||||
output.space();
|
output.space();
|
||||||
output.print_name(alias);
|
print_alias(alias, output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -1127,7 +1132,7 @@ function OutputStream(options) {
|
|||||||
output.print("from");
|
output.print("from");
|
||||||
output.space();
|
output.space();
|
||||||
}
|
}
|
||||||
output.print_string(self.path, self.quote);
|
self.path.print(output);
|
||||||
output.semicolon();
|
output.semicolon();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1257,6 +1262,11 @@ function OutputStream(options) {
|
|||||||
}
|
}
|
||||||
print_method(self, output);
|
print_method(self, output);
|
||||||
});
|
});
|
||||||
|
DEFPRINT(AST_ClassInit, function(output) {
|
||||||
|
output.print("static");
|
||||||
|
output.space();
|
||||||
|
print_braced(this.value, output);
|
||||||
|
});
|
||||||
|
|
||||||
/* -----[ jumps ]----- */
|
/* -----[ jumps ]----- */
|
||||||
function print_jump(kind, prop) {
|
function print_jump(kind, prop) {
|
||||||
@@ -1732,19 +1742,19 @@ function OutputStream(options) {
|
|||||||
var name = get_symbol_name(self);
|
var name = get_symbol_name(self);
|
||||||
output.print_name(name);
|
output.print_name(name);
|
||||||
var alias = self.alias;
|
var alias = self.alias;
|
||||||
if (alias != name) {
|
if (alias.value != name) {
|
||||||
output.space();
|
output.space();
|
||||||
output.print("as");
|
output.print("as");
|
||||||
output.space();
|
output.space();
|
||||||
output.print_name(alias);
|
print_alias(alias, output);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_SymbolImport, function(output) {
|
DEFPRINT(AST_SymbolImport, function(output) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var name = get_symbol_name(self);
|
var name = get_symbol_name(self);
|
||||||
var key = self.key;
|
var key = self.key;
|
||||||
if (key && key != name) {
|
if (key.value && key.value != name) {
|
||||||
output.print_name(key);
|
print_alias(key, output);
|
||||||
output.space();
|
output.space();
|
||||||
output.print("as");
|
output.print("as");
|
||||||
output.space();
|
output.space();
|
||||||
@@ -1814,9 +1824,6 @@ function OutputStream(options) {
|
|||||||
case "\u2029": return "\\u2029";
|
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) {
|
function force_statement(stat, output) {
|
||||||
|
|||||||
128
lib/parse.js
128
lib/parse.js
@@ -552,16 +552,8 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
|
|
||||||
function handle_dot() {
|
function handle_dot() {
|
||||||
next();
|
next();
|
||||||
var ch = peek();
|
if (looking_at("..")) return token("operator", "." + next() + next());
|
||||||
if (ch == ".") {
|
return is_digit(peek().charCodeAt(0)) ? read_num(".") : token("punc", ".");
|
||||||
var op = ".";
|
|
||||||
do {
|
|
||||||
op += ".";
|
|
||||||
next();
|
|
||||||
} while (peek() == ".");
|
|
||||||
return token("operator", op);
|
|
||||||
}
|
|
||||||
return is_digit(ch.charCodeAt(0)) ? read_num(".") : token("punc", ".");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function read_word() {
|
function read_word() {
|
||||||
@@ -815,7 +807,7 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var statement = embed_tokens(function() {
|
var statement = embed_tokens(function(toplevel) {
|
||||||
handle_regexp();
|
handle_regexp();
|
||||||
switch (S.token.type) {
|
switch (S.token.type) {
|
||||||
case "string":
|
case "string":
|
||||||
@@ -854,15 +846,15 @@ function parse($TEXT, options) {
|
|||||||
if (S.in_async) return simple_statement();
|
if (S.in_async) return simple_statement();
|
||||||
break;
|
break;
|
||||||
case "export":
|
case "export":
|
||||||
|
if (!toplevel && options.module !== "") unexpected();
|
||||||
next();
|
next();
|
||||||
return export_();
|
return export_();
|
||||||
case "import":
|
case "import":
|
||||||
var token = peek();
|
var token = peek();
|
||||||
if (!(token.type == "punc" && /^[(.]$/.test(token.value))) {
|
if (token.type == "punc" && /^[(.]$/.test(token.value)) break;
|
||||||
|
if (!toplevel && options.module !== "") unexpected();
|
||||||
next();
|
next();
|
||||||
return import_();
|
return import_();
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "let":
|
case "let":
|
||||||
if (is_vardefs()) {
|
if (is_vardefs()) {
|
||||||
next();
|
next();
|
||||||
@@ -1119,6 +1111,18 @@ function parse($TEXT, options) {
|
|||||||
}));
|
}));
|
||||||
continue;
|
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 internal = is("name") && /^#/.test(S.token.value);
|
||||||
var key = as_property_key();
|
var key = as_property_key();
|
||||||
if (is("punc", "(")) {
|
if (is("punc", "(")) {
|
||||||
@@ -1335,9 +1339,11 @@ function parse($TEXT, options) {
|
|||||||
var loop = S.in_loop;
|
var loop = S.in_loop;
|
||||||
var labels = S.labels;
|
var labels = S.labels;
|
||||||
++S.in_function;
|
++S.in_function;
|
||||||
|
S.input.push_directives_stack();
|
||||||
S.in_loop = 0;
|
S.in_loop = 0;
|
||||||
S.labels = [];
|
S.labels = [];
|
||||||
if (is("punc", "{")) {
|
if (is("punc", "{")) {
|
||||||
|
S.in_directives = true;
|
||||||
body = block_();
|
body = block_();
|
||||||
value = null;
|
value = null;
|
||||||
} else {
|
} else {
|
||||||
@@ -1345,6 +1351,8 @@ function parse($TEXT, options) {
|
|||||||
handle_regexp();
|
handle_regexp();
|
||||||
value = maybe_assign();
|
value = maybe_assign();
|
||||||
}
|
}
|
||||||
|
var is_strict = S.input.has_directive("use strict");
|
||||||
|
S.input.pop_directives_stack();
|
||||||
--S.in_function;
|
--S.in_function;
|
||||||
S.in_loop = loop;
|
S.in_loop = loop;
|
||||||
S.labels = labels;
|
S.labels = labels;
|
||||||
@@ -1358,7 +1366,7 @@ function parse($TEXT, options) {
|
|||||||
value: value,
|
value: value,
|
||||||
end: prev(),
|
end: prev(),
|
||||||
});
|
});
|
||||||
if (S.input.has_directive("use strict")) node.each_argname(strict_verify_symbol);
|
if (is_strict) node.each_argname(strict_verify_symbol);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1426,28 +1434,41 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function is_alias() {
|
function is_alias() {
|
||||||
return is("name") || is_identifier_string(S.token.value);
|
return is("name") || is("string") || is_identifier_string(S.token.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function make_string(token) {
|
||||||
|
return new AST_String({
|
||||||
|
start: token,
|
||||||
|
quote: token.quote,
|
||||||
|
value: token.value,
|
||||||
|
end: token,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function as_path() {
|
||||||
|
var path = S.token;
|
||||||
|
expect_token("string");
|
||||||
|
semicolon();
|
||||||
|
return make_string(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
function export_() {
|
function export_() {
|
||||||
if (is("operator", "*")) {
|
if (is("operator", "*")) {
|
||||||
|
var key = S.token;
|
||||||
|
var alias = key;
|
||||||
next();
|
next();
|
||||||
var alias = "*";
|
|
||||||
if (is("name", "as")) {
|
if (is("name", "as")) {
|
||||||
next();
|
next();
|
||||||
if (!is_alias()) expect_token("name");
|
if (!is_alias()) expect_token("name");
|
||||||
alias = S.token.value;
|
alias = S.token;
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
expect_token("name", "from");
|
expect_token("name", "from");
|
||||||
var path = S.token;
|
|
||||||
expect_token("string");
|
|
||||||
semicolon();
|
|
||||||
return new AST_ExportForeign({
|
return new AST_ExportForeign({
|
||||||
aliases: [ alias ],
|
aliases: [ make_string(alias) ],
|
||||||
keys: [ "*" ],
|
keys: [ make_string(key) ],
|
||||||
path: path.value,
|
path: as_path(),
|
||||||
quote: path.quote,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (is("punc", "{")) {
|
if (is("punc", "{")) {
|
||||||
@@ -1461,26 +1482,20 @@ function parse($TEXT, options) {
|
|||||||
if (is("name", "as")) {
|
if (is("name", "as")) {
|
||||||
next();
|
next();
|
||||||
if (!is_alias()) expect_token("name");
|
if (!is_alias()) expect_token("name");
|
||||||
aliases.push(S.token.value);
|
aliases.push(S.token);
|
||||||
next();
|
next();
|
||||||
} else {
|
} else {
|
||||||
aliases.push(key.value);
|
aliases.push(key);
|
||||||
}
|
}
|
||||||
if (!is("punc", "}")) expect(",");
|
if (!is("punc", "}")) expect(",");
|
||||||
}
|
}
|
||||||
expect("}");
|
expect("}");
|
||||||
if (is("name", "from")) {
|
if (is("name", "from")) {
|
||||||
next();
|
next();
|
||||||
var path = S.token;
|
|
||||||
expect_token("string");
|
|
||||||
semicolon();
|
|
||||||
return new AST_ExportForeign({
|
return new AST_ExportForeign({
|
||||||
aliases: aliases,
|
aliases: aliases.map(make_string),
|
||||||
keys: keys.map(function(token) {
|
keys: keys.map(make_string),
|
||||||
return token.value;
|
path: as_path(),
|
||||||
}),
|
|
||||||
path: path.value,
|
|
||||||
quote: path.quote,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
semicolon();
|
semicolon();
|
||||||
@@ -1488,7 +1503,7 @@ function parse($TEXT, options) {
|
|||||||
properties: keys.map(function(token, index) {
|
properties: keys.map(function(token, index) {
|
||||||
if (!is_token(token, "name")) token_error(token, "Name expected");
|
if (!is_token(token, "name")) token_error(token, "Name expected");
|
||||||
var sym = _make_symbol(AST_SymbolExport, token);
|
var sym = _make_symbol(AST_SymbolExport, token);
|
||||||
sym.alias = aliases[index];
|
sym.alias = make_string(aliases[index]);
|
||||||
return sym;
|
return sym;
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
@@ -1578,26 +1593,42 @@ function parse($TEXT, options) {
|
|||||||
var all = null;
|
var all = null;
|
||||||
var def = as_symbol(AST_SymbolImport, true);
|
var def = as_symbol(AST_SymbolImport, true);
|
||||||
var props = null;
|
var props = null;
|
||||||
if (def ? (def.key = "", is("punc", ",") && next()) : !is("string")) {
|
var cont;
|
||||||
|
if (def) {
|
||||||
|
def.key = new AST_String({
|
||||||
|
start: def.start,
|
||||||
|
value: "",
|
||||||
|
end: def.end,
|
||||||
|
});
|
||||||
|
if (cont = is("punc", ",")) next();
|
||||||
|
} else {
|
||||||
|
cont = !is("string");
|
||||||
|
}
|
||||||
|
if (cont) {
|
||||||
if (is("operator", "*")) {
|
if (is("operator", "*")) {
|
||||||
|
var key = S.token;
|
||||||
next();
|
next();
|
||||||
expect_token("name", "as");
|
expect_token("name", "as");
|
||||||
all = as_symbol(AST_SymbolImport);
|
all = as_symbol(AST_SymbolImport);
|
||||||
all.key = "*";
|
all.key = make_string(key);
|
||||||
} else {
|
} else {
|
||||||
expect("{");
|
expect("{");
|
||||||
props = [];
|
props = [];
|
||||||
while (is_alias()) {
|
while (is_alias()) {
|
||||||
var alias;
|
var alias;
|
||||||
if (is_token(peek(), "name", "as")) {
|
if (is_token(peek(), "name", "as")) {
|
||||||
var key = S.token.value;
|
var key = S.token;
|
||||||
next();
|
next();
|
||||||
next();
|
next();
|
||||||
alias = as_symbol(AST_SymbolImport);
|
alias = as_symbol(AST_SymbolImport);
|
||||||
alias.key = key;
|
alias.key = make_string(key);
|
||||||
} else {
|
} else {
|
||||||
alias = as_symbol(AST_SymbolImport);
|
alias = as_symbol(AST_SymbolImport);
|
||||||
alias.key = alias.name;
|
alias.key = new AST_String({
|
||||||
|
start: alias.start,
|
||||||
|
value: alias.name,
|
||||||
|
end: alias.end,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
props.push(alias);
|
props.push(alias);
|
||||||
if (!is("punc", "}")) expect(",");
|
if (!is("punc", "}")) expect(",");
|
||||||
@@ -1606,15 +1637,11 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (all || def || props) expect_token("name", "from");
|
if (all || def || props) expect_token("name", "from");
|
||||||
var path = S.token;
|
|
||||||
expect_token("string");
|
|
||||||
semicolon();
|
|
||||||
return new AST_Import({
|
return new AST_Import({
|
||||||
all: all,
|
all: all,
|
||||||
default: def,
|
default: def,
|
||||||
path: path.value,
|
path: as_path(),
|
||||||
properties: props,
|
properties: props,
|
||||||
quote: path.quote,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2541,10 +2568,13 @@ function parse($TEXT, options) {
|
|||||||
return function() {
|
return function() {
|
||||||
var start = S.token;
|
var start = S.token;
|
||||||
var body = [];
|
var body = [];
|
||||||
if (options.module) S.input.add_directive("use strict");
|
if (options.module) {
|
||||||
|
S.in_async = true;
|
||||||
|
S.input.add_directive("use strict");
|
||||||
|
}
|
||||||
S.input.push_directives_stack();
|
S.input.push_directives_stack();
|
||||||
while (!is("eof"))
|
while (!is("eof"))
|
||||||
body.push(statement());
|
body.push(statement(true));
|
||||||
S.input.pop_directives_stack();
|
S.input.pop_directives_stack();
|
||||||
var end = prev() || start;
|
var end = prev() || start;
|
||||||
var toplevel = options.toplevel;
|
var toplevel = options.toplevel;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
||||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"version": "3.16.0",
|
"version": "3.16.3",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
},
|
},
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
"LICENSE"
|
"LICENSE"
|
||||||
],
|
],
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"acorn": "~8.2.1",
|
"acorn": "~8.7.1",
|
||||||
"semver": "~6.3.0"
|
"semver": "~6.3.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ function make_code(ast, options) {
|
|||||||
function parse_test(file) {
|
function parse_test(file) {
|
||||||
var script = fs.readFileSync(file, "utf8");
|
var script = fs.readFileSync(file, "utf8");
|
||||||
try {
|
try {
|
||||||
var ast = U.parse(script, { filename: file });
|
var ast = U.parse(script, { filename: file, module: "" });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Caught error while parsing tests in " + file);
|
console.error("Caught error while parsing tests in " + file);
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
|||||||
@@ -1073,7 +1073,7 @@ issue_5414_2: {
|
|||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_5416: {
|
issue_5416_1: {
|
||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
@@ -1095,10 +1095,11 @@ issue_5416: {
|
|||||||
expect: {
|
expect: {
|
||||||
var f = () => {
|
var f = () => {
|
||||||
{
|
{
|
||||||
arguments = void 0;
|
|
||||||
console;
|
console;
|
||||||
|
arguments = void 0,
|
||||||
console.log(arguments);
|
console.log(arguments);
|
||||||
var arguments;
|
var arguments;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
f();
|
f();
|
||||||
@@ -1106,3 +1107,108 @@ issue_5416: {
|
|||||||
expect_stdout: "undefined"
|
expect_stdout: "undefined"
|
||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_5416_2: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
loops: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var f = () => {
|
||||||
|
while ((() => {
|
||||||
|
console;
|
||||||
|
var a = function g(arguments) {
|
||||||
|
while (console.log(arguments));
|
||||||
|
}();
|
||||||
|
})());
|
||||||
|
};
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var f = () => {
|
||||||
|
{
|
||||||
|
console;
|
||||||
|
var arguments = void 0;
|
||||||
|
for (; console.log(arguments););
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5416_3: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var f = () => {
|
||||||
|
(() => {
|
||||||
|
var a = function g(arguments) {
|
||||||
|
console.log(arguments);
|
||||||
|
}();
|
||||||
|
})();
|
||||||
|
};
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var f = () => {
|
||||||
|
arguments = void 0,
|
||||||
|
console.log(arguments);
|
||||||
|
var arguments;
|
||||||
|
};
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5416_4: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
inline: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var f = () => {
|
||||||
|
(() => {
|
||||||
|
var a = function g(arguments) {
|
||||||
|
while (console.log(arguments));
|
||||||
|
}();
|
||||||
|
})();
|
||||||
|
};
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var f = () => {
|
||||||
|
var arguments = void 0;
|
||||||
|
while (console.log(arguments));
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
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"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1046,6 +1046,60 @@ collapse_vars_3: {
|
|||||||
node_version: ">=8"
|
node_version: ">=8"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
collapse_funarg_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
A = "FAIL";
|
||||||
|
var a = "PASS";
|
||||||
|
(async function({}, b) {
|
||||||
|
return b;
|
||||||
|
})(null, A = a);
|
||||||
|
console.log(A);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
A = "FAIL";
|
||||||
|
var a = "PASS";
|
||||||
|
(async function({}, b) {
|
||||||
|
return b;
|
||||||
|
})(null, A = a);
|
||||||
|
console.log(A);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
collapse_funarg_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
A = "FAIL";
|
||||||
|
B = "PASS";
|
||||||
|
(async function() {
|
||||||
|
console.log(function({}, a) {
|
||||||
|
return a;
|
||||||
|
}(null, A = B));
|
||||||
|
})();
|
||||||
|
console.log(A);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
A = "FAIL";
|
||||||
|
B = "PASS";
|
||||||
|
(async function() {
|
||||||
|
console.log(function({}, a) {
|
||||||
|
return a;
|
||||||
|
}(null, A = B));
|
||||||
|
})();
|
||||||
|
console.log(A);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
collapse_property_lambda: {
|
collapse_property_lambda: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
@@ -1293,6 +1347,21 @@ functions_inner_var: {
|
|||||||
node_version: ">=8"
|
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: {
|
issue_4335_1: {
|
||||||
options = {
|
options = {
|
||||||
inline: true,
|
inline: true,
|
||||||
@@ -2961,3 +3030,202 @@ issue_5478: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
node_version: ">=8"
|
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"
|
||||||
|
}
|
||||||
|
|||||||
@@ -241,6 +241,208 @@ class_super: {
|
|||||||
node_version: ">=4"
|
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: {
|
block_scoped: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
@@ -1064,6 +1266,105 @@ keep_fnames: {
|
|||||||
node_version: ">=4"
|
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: {
|
issue_805_1: {
|
||||||
options = {
|
options = {
|
||||||
inline: true,
|
inline: true,
|
||||||
@@ -2882,3 +3183,260 @@ issue_5481: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
node_version: ">=4"
|
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"
|
||||||
|
}
|
||||||
|
|||||||
@@ -9979,3 +9979,25 @@ issue_5396: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_5568: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
A = "FAIL";
|
||||||
|
var a = (A = "PASS", !1);
|
||||||
|
for (var b in a);
|
||||||
|
console.log(A);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
A = "FAIL";
|
||||||
|
for (var b in !(A = "PASS"));
|
||||||
|
console.log(A);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -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: {
|
dont_change_in_or_instanceof_expressions: {
|
||||||
input: {
|
input: {
|
||||||
1 in 1;
|
1 in 1;
|
||||||
|
|||||||
@@ -196,6 +196,88 @@ ifs_7: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
merge_tail_1: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
var b = "foo";
|
||||||
|
if (a) {
|
||||||
|
while (console.log("bar"));
|
||||||
|
console.log(b);
|
||||||
|
} else {
|
||||||
|
while (console.log("baz"));
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
f(42);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
var b = "foo";
|
||||||
|
if (a)
|
||||||
|
while (console.log("bar"));
|
||||||
|
else
|
||||||
|
while (console.log("baz"));
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
f(42);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"baz",
|
||||||
|
"foo",
|
||||||
|
"bar",
|
||||||
|
"foo",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
merge_tail_2: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
var b = "foo";
|
||||||
|
if (a) {
|
||||||
|
while (console.log("bar"));
|
||||||
|
console.log(b);
|
||||||
|
} else {
|
||||||
|
c = "baz";
|
||||||
|
while (console.log(c));
|
||||||
|
while (console.log("bar"));
|
||||||
|
console.log(b);
|
||||||
|
var c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
f(42);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
var b = "foo";
|
||||||
|
if (!a) {
|
||||||
|
c = "baz";
|
||||||
|
while (console.log(c));
|
||||||
|
var c;
|
||||||
|
}
|
||||||
|
while (console.log("bar"));
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
f(42);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"baz",
|
||||||
|
"bar",
|
||||||
|
"foo",
|
||||||
|
"bar",
|
||||||
|
"foo",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
cond_1: {
|
cond_1: {
|
||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
@@ -1731,7 +1813,7 @@ issue_3576: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_3668: {
|
issue_3668_1: {
|
||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
if_return: true,
|
if_return: true,
|
||||||
@@ -1748,6 +1830,38 @@ issue_3668: {
|
|||||||
}
|
}
|
||||||
console.log(f());
|
console.log(f());
|
||||||
}
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
try {
|
||||||
|
var undefined = typeof f;
|
||||||
|
if (!f) return undefined;
|
||||||
|
} catch (e) {
|
||||||
|
return "FAIL";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3668_2: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
try {
|
||||||
|
var undefined = typeof f;
|
||||||
|
if (!f) return undefined;
|
||||||
|
return;
|
||||||
|
} catch (e) {
|
||||||
|
return "FAIL";
|
||||||
|
}
|
||||||
|
FAIL;
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f() {
|
function f() {
|
||||||
try {
|
try {
|
||||||
@@ -1756,6 +1870,7 @@ issue_3668: {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
return "FAIL";
|
return "FAIL";
|
||||||
}
|
}
|
||||||
|
FAIL;
|
||||||
}
|
}
|
||||||
console.log(f());
|
console.log(f());
|
||||||
}
|
}
|
||||||
@@ -2062,3 +2177,176 @@ issue_5334_2: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_5544_1: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
if (a)
|
||||||
|
switch (42) {
|
||||||
|
case console.log("FAIL"):
|
||||||
|
case console:
|
||||||
|
}
|
||||||
|
else
|
||||||
|
switch (false) {
|
||||||
|
case console.log("PASS"):
|
||||||
|
case console:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
if (a)
|
||||||
|
switch (42) {
|
||||||
|
case console.log("FAIL"):
|
||||||
|
case console:
|
||||||
|
}
|
||||||
|
else
|
||||||
|
switch (false) {
|
||||||
|
case console.log("PASS"):
|
||||||
|
case console:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5544_2: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
if (a)
|
||||||
|
switch (42) {
|
||||||
|
case console.log("FAIL"):
|
||||||
|
case console:
|
||||||
|
}
|
||||||
|
else
|
||||||
|
switch (42) {
|
||||||
|
case console.log("PASS"):
|
||||||
|
case console:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
if (a)
|
||||||
|
switch (42) {
|
||||||
|
case console.log("FAIL"):
|
||||||
|
case console:
|
||||||
|
}
|
||||||
|
else
|
||||||
|
switch (42) {
|
||||||
|
case console.log("PASS"):
|
||||||
|
case console:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5546_1: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
if (a)
|
||||||
|
try {
|
||||||
|
console;
|
||||||
|
} finally {
|
||||||
|
console.log("FAIL");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
try {
|
||||||
|
console;
|
||||||
|
} finally {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
if (a)
|
||||||
|
try {
|
||||||
|
console;
|
||||||
|
} finally {
|
||||||
|
console.log("FAIL");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
try {
|
||||||
|
console;
|
||||||
|
} finally {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5546_2: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
if (a)
|
||||||
|
try {
|
||||||
|
console;
|
||||||
|
} catch (e) {}
|
||||||
|
else
|
||||||
|
try {
|
||||||
|
console;
|
||||||
|
} finally {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
if (a)
|
||||||
|
try {
|
||||||
|
console;
|
||||||
|
} catch (e) {}
|
||||||
|
else
|
||||||
|
try {
|
||||||
|
console;
|
||||||
|
} finally {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5546_3: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
if (a)
|
||||||
|
try {
|
||||||
|
FAIL;
|
||||||
|
} catch (e) {
|
||||||
|
console.log("FAIL");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
try {
|
||||||
|
FAIL;
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
if (a)
|
||||||
|
try {
|
||||||
|
FAIL;
|
||||||
|
} catch (e) {
|
||||||
|
console.log("FAIL");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
try {
|
||||||
|
FAIL;
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -142,6 +142,80 @@ if_dead_branch: {
|
|||||||
expect_stdout: "undefined"
|
expect_stdout: "undefined"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
retain_tail_1: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
var b = "foo";
|
||||||
|
if (a) {
|
||||||
|
const b = "bar";
|
||||||
|
while (console.log("baz"));
|
||||||
|
console.log(b);
|
||||||
|
} else {
|
||||||
|
while (console.log("moo"));
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
f(42);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
var b = "foo";
|
||||||
|
if (a) {
|
||||||
|
const b = "bar";
|
||||||
|
while (console.log("baz"));
|
||||||
|
console.log(b);
|
||||||
|
} else {
|
||||||
|
while (console.log("moo"));
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
f(42);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
retain_tail_2: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
var b = "foo";
|
||||||
|
if (a) {
|
||||||
|
while (console.log("bar"));
|
||||||
|
console.log(b);
|
||||||
|
} else {
|
||||||
|
const b = "baz";
|
||||||
|
while (console.log("moo"));
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
f(42);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
var b = "foo";
|
||||||
|
if (a) {
|
||||||
|
while (console.log("bar"));
|
||||||
|
console.log(b);
|
||||||
|
} else {
|
||||||
|
const b = "baz";
|
||||||
|
while (console.log("moo"));
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
f(42);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
merge_vars_1: {
|
merge_vars_1: {
|
||||||
options = {
|
options = {
|
||||||
merge_vars: true,
|
merge_vars: true,
|
||||||
@@ -579,6 +653,37 @@ dead_block_after_return: {
|
|||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if_return_3: {
|
||||||
|
options = {
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS";
|
||||||
|
function f(b) {
|
||||||
|
if (console) {
|
||||||
|
const b = a;
|
||||||
|
return b;
|
||||||
|
} else
|
||||||
|
while (console.log("FAIL 1"));
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
console.log(f("FAIL 2"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "PASS";
|
||||||
|
function f(b) {
|
||||||
|
if (console) {
|
||||||
|
const b = a;
|
||||||
|
return b;
|
||||||
|
} else
|
||||||
|
while (console.log("FAIL 1"));
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
console.log(f("FAIL 2"));
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
do_if_continue_1: {
|
do_if_continue_1: {
|
||||||
options = {
|
options = {
|
||||||
if_return: true,
|
if_return: true,
|
||||||
@@ -1872,3 +1977,37 @@ issue_5476: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "undefined"
|
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"
|
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",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
@@ -180,6 +180,26 @@ collapse_arg_sequence: {
|
|||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
collapse_in_arg: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a, b = a) {
|
||||||
|
b("PASS");
|
||||||
|
})(console.log);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a) {
|
||||||
|
a("PASS");
|
||||||
|
})(console.log);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
collapse_value_1: {
|
collapse_value_1: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
@@ -541,7 +561,7 @@ inline_side_effects_2: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a = 42;
|
var a = 42;
|
||||||
[ [].e = --a ] = [ console ];
|
[ [][0] = --a ] = [ console ];
|
||||||
console.log(a);
|
console.log(a);
|
||||||
}
|
}
|
||||||
expect_stdout: "42"
|
expect_stdout: "42"
|
||||||
@@ -1170,6 +1190,49 @@ mangle_arrow_2_toplevel: {
|
|||||||
node_version: ">=6.9.3"
|
node_version: ">=6.9.3"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
collapse_preceding_simple_arg: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "foo";
|
||||||
|
console.log(function(b, c = "bar") {
|
||||||
|
return b + c;
|
||||||
|
}(a, a));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "foo";
|
||||||
|
console.log(function(b, c = "bar") {
|
||||||
|
return a + c;
|
||||||
|
}(0, a));
|
||||||
|
}
|
||||||
|
expect_stdout: "foofoo"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_preceding_simple_arg: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "foo";
|
||||||
|
console.log(function(b, c = "bar") {
|
||||||
|
return b + c;
|
||||||
|
}(a, a));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "foo";
|
||||||
|
console.log(function(c = "bar") {
|
||||||
|
return a + c;
|
||||||
|
}(a));
|
||||||
|
}
|
||||||
|
expect_stdout: "foofoo"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
issue_4444: {
|
issue_4444: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
@@ -1558,7 +1621,7 @@ issue_4502_4: {
|
|||||||
(function(a, b = console.log("FAIL")) {})(..."" + console.log(42));
|
(function(a, b = console.log("FAIL")) {})(..."" + console.log(42));
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
[ , [].e = console.log("FAIL") ] = [ ..."" + console.log(42) ];
|
[ , [][0] = console.log("FAIL") ] = [ ..."" + console.log(42) ];
|
||||||
}
|
}
|
||||||
expect_stdout: "42"
|
expect_stdout: "42"
|
||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
@@ -2183,7 +2246,7 @@ issue_5340_2: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a;
|
var a;
|
||||||
[ [].e = 0 ] = [ ({ p: a } = true).q ];
|
[ [][0] = 0 ] = [ ({ p: a } = true).q ];
|
||||||
console.log(a);
|
console.log(a);
|
||||||
}
|
}
|
||||||
expect_stdout: "undefined"
|
expect_stdout: "undefined"
|
||||||
@@ -2462,3 +2525,494 @@ issue_5485: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
node_version: ">=6"
|
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"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5566_1: {
|
||||||
|
options = {
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a, f = function() {
|
||||||
|
return a;
|
||||||
|
}) {
|
||||||
|
var a = "foo";
|
||||||
|
console.log(a, f());
|
||||||
|
})("bar");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a, f = function() {
|
||||||
|
return a;
|
||||||
|
}) {
|
||||||
|
var a = "foo";
|
||||||
|
console.log(a, f());
|
||||||
|
})("bar");
|
||||||
|
}
|
||||||
|
expect_stdout: "foo bar"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5566_2: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a, f = function() {
|
||||||
|
return a;
|
||||||
|
}) {
|
||||||
|
function a() {}
|
||||||
|
console.log(typeof a, typeof f());
|
||||||
|
})(42);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a, f = function() {
|
||||||
|
return a;
|
||||||
|
}) {
|
||||||
|
function a() {}
|
||||||
|
console.log(typeof a, typeof f());
|
||||||
|
})(42);
|
||||||
|
}
|
||||||
|
expect_stdout: "function number"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5566_3: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a, f = function() {
|
||||||
|
return a;
|
||||||
|
}) {
|
||||||
|
function a() {}
|
||||||
|
console.log(typeof a, typeof f());
|
||||||
|
})(42);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a, f = function() {
|
||||||
|
return a;
|
||||||
|
}) {
|
||||||
|
function a() {}
|
||||||
|
console.log(typeof a, typeof f());
|
||||||
|
})(42);
|
||||||
|
}
|
||||||
|
expect_stdout: "function number"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5566_4: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a, b = function() {
|
||||||
|
return a;
|
||||||
|
}) {
|
||||||
|
var a = 0;
|
||||||
|
b()("PASS");
|
||||||
|
})(console.log);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a, b = function() {
|
||||||
|
return a;
|
||||||
|
}) {
|
||||||
|
var a = 0;
|
||||||
|
b()("PASS");
|
||||||
|
})(console.log);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5566_5: {
|
||||||
|
options = {
|
||||||
|
hoist_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a, f = function() {
|
||||||
|
return a;
|
||||||
|
}) {
|
||||||
|
var a = "foo";
|
||||||
|
var b;
|
||||||
|
console.log(a, f());
|
||||||
|
})("bar");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a, f = function() {
|
||||||
|
return a;
|
||||||
|
}) {
|
||||||
|
var b, a = "foo";
|
||||||
|
console.log(a, f());
|
||||||
|
})("bar");
|
||||||
|
}
|
||||||
|
expect_stdout: "foo bar"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|||||||
@@ -472,6 +472,93 @@ funarg_collapse_vars_3: {
|
|||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
funarg_collapse_vars_4: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS";
|
||||||
|
(function(b, { log: c }) {
|
||||||
|
c(b);
|
||||||
|
})(a, console);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "PASS";
|
||||||
|
(function(b, { log: c }) {
|
||||||
|
c(a);
|
||||||
|
})(0, console);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
funarg_collapse_vars_5: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
A = "FAIL";
|
||||||
|
B = "PASS";
|
||||||
|
try {
|
||||||
|
console.log(function({}, a) {
|
||||||
|
return a;
|
||||||
|
}(null, A = B));
|
||||||
|
} catch (e) {}
|
||||||
|
console.log(A);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
A = "FAIL";
|
||||||
|
B = "PASS";
|
||||||
|
try {
|
||||||
|
console.log(function({}, a) {
|
||||||
|
return a;
|
||||||
|
}(null, A = B));
|
||||||
|
} catch (e) {}
|
||||||
|
console.log(A);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
funarg_collapse_vars_6: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
A = "FAIL";
|
||||||
|
B = "PASS";
|
||||||
|
function f() {
|
||||||
|
console.log(function({}, a) {
|
||||||
|
return a;
|
||||||
|
}(null, A = B));
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
f();
|
||||||
|
} catch (e) {
|
||||||
|
console.log(A);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
A = "FAIL";
|
||||||
|
B = "PASS";
|
||||||
|
function f() {
|
||||||
|
console.log(function({}, a) {
|
||||||
|
return a;
|
||||||
|
}(null, A = B));
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
f();
|
||||||
|
} catch (e) {
|
||||||
|
console.log(A);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
funarg_reduce_vars_1: {
|
funarg_reduce_vars_1: {
|
||||||
options = {
|
options = {
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
@@ -3497,7 +3584,7 @@ issue_5314_2: {
|
|||||||
A = this;
|
A = this;
|
||||||
new function() {
|
new function() {
|
||||||
[ {
|
[ {
|
||||||
[console.log(this === A ? "FAIL" : "PASS")]: [].e,
|
[console.log(this === A ? "FAIL" : "PASS")]: [][0],
|
||||||
} ] = [ 42 ];
|
} ] = [ 42 ];
|
||||||
}();
|
}();
|
||||||
}
|
}
|
||||||
@@ -3646,3 +3733,114 @@ issue_5485: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
node_version: ">=6"
|
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"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5573: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var log = console.log;
|
||||||
|
var a = "FAIL";
|
||||||
|
(function([ { [log(a)]: b } ]) {
|
||||||
|
A = 42;
|
||||||
|
})((a = "PASS", [ {} ]));
|
||||||
|
log(a, A);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var log = console.log;
|
||||||
|
var a = "FAIL";
|
||||||
|
(function([ { [log(a)]: b } ]) {
|
||||||
|
A = 42;
|
||||||
|
})((a = "PASS", [ {} ]));
|
||||||
|
log(a, A);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"PASS",
|
||||||
|
"PASS 42",
|
||||||
|
]
|
||||||
|
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: {
|
issue_1539: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
@@ -3615,3 +3685,85 @@ issue_5271: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "42"
|
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: {
|
issue_1649: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
@@ -3376,3 +3390,29 @@ issue_5380: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_5558: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 99, b = 0;
|
||||||
|
a++;
|
||||||
|
b++;
|
||||||
|
b += a;
|
||||||
|
b *= a;
|
||||||
|
b += a;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 99, b = 0;
|
||||||
|
b++,
|
||||||
|
b = (b += ++a) * a + a,
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "100"
|
||||||
|
}
|
||||||
|
|||||||
@@ -109,6 +109,17 @@ foreign: {
|
|||||||
expect_exact: 'export*from"foo";export{}from"bar";export*as a from"baz";export{default}from"moo";export{b,c as case,default as delete,d}from"moz";'
|
expect_exact: 'export*from"foo";export{}from"bar";export*as a from"baz";export{default}from"moo";export{b,c as case,default as delete,d}from"moz";'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
non_identifiers: {
|
||||||
|
beautify = {
|
||||||
|
quote_style: 3,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
export * as "42" from 'foo';
|
||||||
|
export { '42', "delete" as 'foo' } from "bar";
|
||||||
|
}
|
||||||
|
expect_exact: "export*as\"42\"from'foo';export{'42',delete as foo}from\"bar\";"
|
||||||
|
}
|
||||||
|
|
||||||
same_quotes: {
|
same_quotes: {
|
||||||
beautify = {
|
beautify = {
|
||||||
beautify: true,
|
beautify: true,
|
||||||
@@ -417,6 +428,46 @@ hoist_funs: {
|
|||||||
expect_exact: "export function f(){}export default async function*g(){}"
|
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: {
|
issue_4742_join_vars_1: {
|
||||||
options = {
|
options = {
|
||||||
join_vars: true,
|
join_vars: true,
|
||||||
|
|||||||
@@ -629,7 +629,7 @@ inline_binary_and: {
|
|||||||
return void "moo";
|
return void "moo";
|
||||||
return;
|
return;
|
||||||
} else
|
} else
|
||||||
return;
|
return void 0;
|
||||||
}());
|
}());
|
||||||
}
|
}
|
||||||
expect_stdout: [
|
expect_stdout: [
|
||||||
@@ -5582,7 +5582,7 @@ issue_3835: {
|
|||||||
return f();
|
return f();
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: RangeError("Maximum call stack size exceeded")
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_3836_1: {
|
issue_3836_1: {
|
||||||
@@ -7835,7 +7835,7 @@ issue_5249_1: {
|
|||||||
while (console.log("FAIL 2"));
|
while (console.log("FAIL 2"));
|
||||||
return;
|
return;
|
||||||
} else
|
} else
|
||||||
return;
|
return void 0;
|
||||||
throw "FAIL 3";
|
throw "FAIL 3";
|
||||||
}());
|
}());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1203,3 +1203,24 @@ issue_5441: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "object"
|
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,546 @@ 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"
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_catch: {
|
||||||
|
options = {
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (e) {
|
||||||
|
return console.log("foo"), "bar";
|
||||||
|
} finally {
|
||||||
|
console.log("baz");
|
||||||
|
}
|
||||||
|
return "bar";
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (e) {
|
||||||
|
console.log("foo");
|
||||||
|
} finally {
|
||||||
|
console.log("baz");
|
||||||
|
}
|
||||||
|
return "bar";
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"foo",
|
||||||
|
"baz",
|
||||||
|
"bar",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
retain_catch: {
|
||||||
|
options = {
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (e) {
|
||||||
|
return console.log("foo");
|
||||||
|
} finally {
|
||||||
|
console.log("bar");
|
||||||
|
}
|
||||||
|
return console.log("foo");
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (e) {
|
||||||
|
return console.log("foo");
|
||||||
|
} finally {
|
||||||
|
console.log("bar");
|
||||||
|
}
|
||||||
|
return console.log("foo");
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"foo",
|
||||||
|
"bar",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
retain_finally: {
|
||||||
|
options = {
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
try {
|
||||||
|
return console.log("foo"), FAIL;
|
||||||
|
} catch (e) {
|
||||||
|
return console.log("bar"), "FAIL";
|
||||||
|
} finally {
|
||||||
|
return console.log("baz"), console.log("moo");
|
||||||
|
}
|
||||||
|
return console.log("moo");
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
try {
|
||||||
|
return console.log("foo"), FAIL;
|
||||||
|
} catch (e) {
|
||||||
|
return console.log("bar"), "FAIL";
|
||||||
|
} finally {
|
||||||
|
return console.log("baz"), console.log("moo");
|
||||||
|
}
|
||||||
|
return console.log("moo");
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"foo",
|
||||||
|
"bar",
|
||||||
|
"baz",
|
||||||
|
"moo",
|
||||||
|
"undefined",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_try: {
|
||||||
|
options = {
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
try {
|
||||||
|
return console.log("foo"), "bar";
|
||||||
|
} finally {
|
||||||
|
console.log("baz");
|
||||||
|
}
|
||||||
|
return "bar";
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
try {
|
||||||
|
console.log("foo");
|
||||||
|
} finally {
|
||||||
|
console.log("baz");
|
||||||
|
}
|
||||||
|
return "bar";
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"foo",
|
||||||
|
"baz",
|
||||||
|
"bar",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
retain_try: {
|
||||||
|
options = {
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
try {
|
||||||
|
return console.log("foo");
|
||||||
|
} finally {
|
||||||
|
console.log("bar");
|
||||||
|
}
|
||||||
|
return console.log("foo");
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
try {
|
||||||
|
return console.log("foo");
|
||||||
|
} finally {
|
||||||
|
console.log("bar");
|
||||||
|
}
|
||||||
|
return console.log("foo");
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"foo",
|
||||||
|
"bar",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_try_catch: {
|
||||||
|
options = {
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
try {
|
||||||
|
if (a())
|
||||||
|
return console.log("foo"), console.log("baz");
|
||||||
|
} catch (e) {
|
||||||
|
return console.log("bar"), console.log("baz");
|
||||||
|
}
|
||||||
|
return console.log("baz");
|
||||||
|
}
|
||||||
|
f(function() {
|
||||||
|
return 42;
|
||||||
|
});
|
||||||
|
f(function() {});
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
try {
|
||||||
|
if (a())
|
||||||
|
console.log("foo");
|
||||||
|
} catch (e) {
|
||||||
|
console.log("bar");
|
||||||
|
}
|
||||||
|
return console.log("baz");
|
||||||
|
}
|
||||||
|
f(function() {
|
||||||
|
return 42;
|
||||||
|
});
|
||||||
|
f(function() {});
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"foo",
|
||||||
|
"baz",
|
||||||
|
"baz",
|
||||||
|
"bar",
|
||||||
|
"baz",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
empty_try: {
|
||||||
|
options = {
|
||||||
|
if_return: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
return f;
|
||||||
|
function f() {
|
||||||
|
try {} finally {}
|
||||||
|
return "PASS";
|
||||||
|
}
|
||||||
|
}()());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
return function() {
|
||||||
|
try {} finally {}
|
||||||
|
return "PASS";
|
||||||
|
};
|
||||||
|
}()());
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
sequence_void_1: {
|
||||||
|
options = {
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
{
|
||||||
|
if (console)
|
||||||
|
return console, void console.log("PASS");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
if (console)
|
||||||
|
console, void console.log("PASS");
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
sequence_void_2: {
|
||||||
|
options = {
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
{
|
||||||
|
if (console)
|
||||||
|
return console, void console.log("PASS");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
FAIL;
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
if (console)
|
||||||
|
console, void console.log("PASS");
|
||||||
|
else {
|
||||||
|
return;
|
||||||
|
FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
tail_match: {
|
||||||
|
options = {
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
if (a) {
|
||||||
|
console.log("foo");
|
||||||
|
return console.log("bar");
|
||||||
|
}
|
||||||
|
while (console.log("baz"));
|
||||||
|
return console.log("moo"), console.log("bar");
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
f(42);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
if (a)
|
||||||
|
console.log("foo");
|
||||||
|
else {
|
||||||
|
while (console.log("baz"));
|
||||||
|
console.log("moo");
|
||||||
|
}
|
||||||
|
return console.log("bar");
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
f(42);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"baz",
|
||||||
|
"moo",
|
||||||
|
"bar",
|
||||||
|
"foo",
|
||||||
|
"bar",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
void_match: {
|
||||||
|
options = {
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
if (a) {
|
||||||
|
console.log("foo");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while (console.log("bar"));
|
||||||
|
return console.log("baz"), void console.log("moo");
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
f(42);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
if (a)
|
||||||
|
console.log("foo");
|
||||||
|
else {
|
||||||
|
while (console.log("bar"));
|
||||||
|
console.log("baz"),
|
||||||
|
console.log("moo");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
f(42);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"bar",
|
||||||
|
"baz",
|
||||||
|
"moo",
|
||||||
|
"foo",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
@@ -40,6 +40,17 @@ default_keys: {
|
|||||||
expect_exact: 'import foo,{bar}from"baz";'
|
expect_exact: 'import foo,{bar}from"baz";'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
non_identifiers: {
|
||||||
|
beautify = {
|
||||||
|
quote_style: 3,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
import { '42' as foo } from "bar";
|
||||||
|
import { "foo" as bar } from 'baz';
|
||||||
|
}
|
||||||
|
expect_exact: "import{'42'as foo}from\"bar\";import{foo as bar}from'baz';"
|
||||||
|
}
|
||||||
|
|
||||||
dynamic: {
|
dynamic: {
|
||||||
input: {
|
input: {
|
||||||
(async a => await import(a))("foo").then(bar);
|
(async a => await import(a))("foo").then(bar);
|
||||||
@@ -227,3 +238,33 @@ issue_4708_2: {
|
|||||||
import a from "foo";
|
import a from "foo";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pr_5550_1: {
|
||||||
|
input: {
|
||||||
|
if (console)
|
||||||
|
import("foo");
|
||||||
|
else
|
||||||
|
import.meta.url.replace(/bar/g, console.log);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
if (console)
|
||||||
|
import("foo");
|
||||||
|
else
|
||||||
|
import.meta.url.replace(/bar/g, console.log);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pr_5550_2: {
|
||||||
|
input: {
|
||||||
|
L: {
|
||||||
|
import("foo");
|
||||||
|
import.meta.url.replace(/bar/g, console.log);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
L: {
|
||||||
|
import("foo");
|
||||||
|
import.meta.url.replace(/bar/g, console.log);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -111,6 +111,7 @@ labels_5: {
|
|||||||
labels_6: {
|
labels_6: {
|
||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
out: break out;
|
out: break out;
|
||||||
@@ -208,6 +209,59 @@ labels_10: {
|
|||||||
expect_stdout: "PASS"
|
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: {
|
issue_4466_1: {
|
||||||
mangle = {
|
mangle = {
|
||||||
v8: false,
|
v8: false,
|
||||||
@@ -327,3 +381,53 @@ issue_4466_2_toplevel_v8: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
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"
|
||||||
|
}
|
||||||
|
|||||||
@@ -190,6 +190,96 @@ if_dead_branch: {
|
|||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
retain_tail_1: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
function f(a) {
|
||||||
|
var b = "foo";
|
||||||
|
if (a) {
|
||||||
|
let b = "bar";
|
||||||
|
while (console.log("baz"));
|
||||||
|
console.log(b);
|
||||||
|
} else {
|
||||||
|
while (console.log("moo"));
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
f(42);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
function f(a) {
|
||||||
|
var b = "foo";
|
||||||
|
if (a) {
|
||||||
|
let b = "bar";
|
||||||
|
while (console.log("baz"));
|
||||||
|
console.log(b);
|
||||||
|
} else {
|
||||||
|
while (console.log("moo"));
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
f(42);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"moo",
|
||||||
|
"foo",
|
||||||
|
"baz",
|
||||||
|
"bar",
|
||||||
|
]
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
retain_tail_2: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
function f(a) {
|
||||||
|
var b = "foo";
|
||||||
|
if (a) {
|
||||||
|
while (console.log("bar"));
|
||||||
|
console.log(b);
|
||||||
|
} else {
|
||||||
|
let b = "baz";
|
||||||
|
while (console.log("moo"));
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
f(42);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
function f(a) {
|
||||||
|
var b = "foo";
|
||||||
|
if (a) {
|
||||||
|
while (console.log("bar"));
|
||||||
|
console.log(b);
|
||||||
|
} else {
|
||||||
|
let b = "baz";
|
||||||
|
while (console.log("moo"));
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
f(42);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"moo",
|
||||||
|
"baz",
|
||||||
|
"bar",
|
||||||
|
"foo",
|
||||||
|
]
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
merge_vars_1: {
|
merge_vars_1: {
|
||||||
options = {
|
options = {
|
||||||
merge_vars: true,
|
merge_vars: true,
|
||||||
@@ -892,6 +982,40 @@ if_return_2: {
|
|||||||
node_version: ">=4"
|
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: {
|
do_if_continue_1: {
|
||||||
options = {
|
options = {
|
||||||
if_return: true,
|
if_return: true,
|
||||||
@@ -1625,7 +1749,7 @@ issue_4438: {
|
|||||||
function f() {
|
function f() {
|
||||||
if (console) {
|
if (console) {
|
||||||
let a = console.log;
|
let a = console.log;
|
||||||
void a("PASS");
|
a("PASS");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f();
|
f();
|
||||||
|
|||||||
@@ -308,6 +308,7 @@ issue_4679: {
|
|||||||
issue_5266: {
|
issue_5266: {
|
||||||
options = {
|
options = {
|
||||||
inline: true,
|
inline: true,
|
||||||
|
side_effects: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ relational: {
|
|||||||
"bar" >= "bar";
|
"bar" >= "bar";
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
bar();
|
0 instanceof bar();
|
||||||
bar();
|
bar();
|
||||||
bar(), bar();
|
bar(), bar();
|
||||||
bar();
|
bar();
|
||||||
|
|||||||
@@ -50,6 +50,22 @@ regexp_properties: {
|
|||||||
expect_stdout: "abc true false 0 false"
|
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: {
|
issue_3434_1: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
|||||||
@@ -648,7 +648,7 @@ drop_new_function: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
void ([ ... {
|
void ([ ... {
|
||||||
[console.log("PASS")]: [].e,
|
[console.log("PASS")]: [][0],
|
||||||
}] = []);
|
}] = []);
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
@@ -1363,3 +1363,264 @@ issue_5391: {
|
|||||||
expect_stdout: "NaN"
|
expect_stdout: "NaN"
|
||||||
node_version: ">=8.3.0"
|
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"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5552_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var log = console.log;
|
||||||
|
var a = f, b = log();
|
||||||
|
function f(...[ c = a = "PASS" ]) {}
|
||||||
|
f((a = "FAIL", b));
|
||||||
|
log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var log = console.log;
|
||||||
|
var a = f, b = log();
|
||||||
|
function f(...[ c = a = "PASS" ]) {}
|
||||||
|
f((a = "FAIL", b));
|
||||||
|
log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"",
|
||||||
|
"PASS",
|
||||||
|
]
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5552_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var log = console.log;
|
||||||
|
var a = f;
|
||||||
|
function f(...{ [a = "PASS"]: b }) {}
|
||||||
|
f((a = "FAIL", 42));
|
||||||
|
log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var log = console.log;
|
||||||
|
var a = f;
|
||||||
|
function f(...{ [a = "PASS"]: b }) {}
|
||||||
|
f((a = "FAIL", 42));
|
||||||
|
log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5552_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = [ "FAIL", "PASS" ];
|
||||||
|
console.log(function(b, ...[ c = a.pop() ]) {
|
||||||
|
return b;
|
||||||
|
}(a.pop()));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = [ "FAIL", "PASS" ];
|
||||||
|
console.log(function(b, ...[ c = a.pop() ]) {
|
||||||
|
return b;
|
||||||
|
}(a.pop()));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5552_4: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = [ "FAIL", "PASS" ];
|
||||||
|
console.log(function(b, ...{ [a.pop()]: c }) {
|
||||||
|
return b;
|
||||||
|
}(a.pop()));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = [ "FAIL", "PASS" ];
|
||||||
|
console.log(function(b, ...{ [a.pop()]: c }) {
|
||||||
|
return b;
|
||||||
|
}(a.pop()));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|||||||
@@ -645,3 +645,56 @@ issue_4751: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
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"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,3 +1,12 @@
|
|||||||
|
decimal: {
|
||||||
|
input: {
|
||||||
|
console.log({... 0.42});
|
||||||
|
}
|
||||||
|
expect_exact: "console.log({....42});"
|
||||||
|
expect_stdout: "{}"
|
||||||
|
node_version: ">=8.3.0"
|
||||||
|
}
|
||||||
|
|
||||||
collapse_vars_1: {
|
collapse_vars_1: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
|
|||||||
@@ -1608,3 +1608,83 @@ issue_5012: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_5543_1: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
switch (a) {
|
||||||
|
default:
|
||||||
|
switch (42) {
|
||||||
|
case a:
|
||||||
|
case console.log("PASS"):
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case null:
|
||||||
|
switch (false) {
|
||||||
|
case a:
|
||||||
|
case console.log("FAIL"):
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
switch (a) {
|
||||||
|
default:
|
||||||
|
switch (42) {
|
||||||
|
case a:
|
||||||
|
case console.log("PASS"):
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case null:
|
||||||
|
switch (false) {
|
||||||
|
case a:
|
||||||
|
case console.log("FAIL"):
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5543_2: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
switch (a) {
|
||||||
|
default:
|
||||||
|
switch (42) {
|
||||||
|
case a:
|
||||||
|
case console.log("PASS"):
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case null:
|
||||||
|
switch (42) {
|
||||||
|
case a:
|
||||||
|
case console.log("FAIL"):
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
switch (a) {
|
||||||
|
default:
|
||||||
|
switch (42) {
|
||||||
|
case a:
|
||||||
|
case console.log("PASS"):
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case null:
|
||||||
|
switch (42) {
|
||||||
|
case a:
|
||||||
|
case console.log("FAIL"):
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ if_return: {
|
|||||||
if (w) {
|
if (w) {
|
||||||
if (y) return;
|
if (y) return;
|
||||||
} else if (z) return;
|
} else if (z) return;
|
||||||
return x == y || (x && w(), y && z()), !0;
|
return x != y && (x && w(), y && z()), !0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -613,3 +613,35 @@ issue_4954: {
|
|||||||
]
|
]
|
||||||
node_version: ">=4"
|
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"
|
||||||
|
}
|
||||||
|
|||||||
@@ -907,7 +907,7 @@ drop_body: {
|
|||||||
})([ console.log("baz") ]);
|
})([ console.log("baz") ]);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
[ [ , [].e = console.log("foo") ] ] = [ [ console.log("baz") ] ];
|
[ [ , [][0] = console.log("foo") ] ] = [ [ console.log("baz") ] ];
|
||||||
}
|
}
|
||||||
expect_stdout: [
|
expect_stdout: [
|
||||||
"baz",
|
"baz",
|
||||||
@@ -934,6 +934,21 @@ drop_unused_call: {
|
|||||||
node_version: ">=4"
|
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: {
|
issue_4454_1: {
|
||||||
rename = false
|
rename = false
|
||||||
options = {
|
options = {
|
||||||
@@ -1168,6 +1183,35 @@ issue_4641_2: {
|
|||||||
node_version: ">=10"
|
node_version: ">=10"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4641_3: {
|
||||||
|
options = {
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(typeof async function*() {
|
||||||
|
try {
|
||||||
|
return void "FAIL";
|
||||||
|
} finally {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}().next().then);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(typeof async function*() {
|
||||||
|
try {
|
||||||
|
return void "FAIL";
|
||||||
|
} finally {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}().next().then);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"function",
|
||||||
|
"PASS",
|
||||||
|
]
|
||||||
|
node_version: ">=10"
|
||||||
|
}
|
||||||
|
|
||||||
issue_4769_1: {
|
issue_4769_1: {
|
||||||
options = {
|
options = {
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
@@ -1452,6 +1496,80 @@ issue_5385_2: {
|
|||||||
node_version: ">=10"
|
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: {
|
issue_5425: {
|
||||||
options = {
|
options = {
|
||||||
assignments: true,
|
assignments: true,
|
||||||
@@ -1515,3 +1633,71 @@ issue_5456: {
|
|||||||
expect_stdout: "foo"
|
expect_stdout: "foo"
|
||||||
node_version: ">=4"
|
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,3 +1,4 @@
|
|||||||
|
var acorn = require("acorn");
|
||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
var UglifyJS = require("../node");
|
var UglifyJS = require("../node");
|
||||||
|
|
||||||
@@ -25,6 +26,7 @@ describe("export", function() {
|
|||||||
"export { * };",
|
"export { * };",
|
||||||
"export { * as A };",
|
"export { * as A };",
|
||||||
"export { 42 as A };",
|
"export { 42 as A };",
|
||||||
|
"export { 'A' as B };",
|
||||||
"export { A as B-C };",
|
"export { A as B-C };",
|
||||||
"export { default as A };",
|
"export { default as A };",
|
||||||
].forEach(function(code) {
|
].forEach(function(code) {
|
||||||
@@ -51,8 +53,11 @@ describe("export", function() {
|
|||||||
it("Should reject invalid `export ... from ...` statement syntax", function() {
|
it("Should reject invalid `export ... from ...` statement syntax", function() {
|
||||||
[
|
[
|
||||||
"export from 'path';",
|
"export from 'path';",
|
||||||
|
"export A from 'path';",
|
||||||
"export * from `path`;",
|
"export * from `path`;",
|
||||||
|
"export 'A' from 'path';",
|
||||||
"export A as B from 'path';",
|
"export A as B from 'path';",
|
||||||
|
"export 'A' as B from 'path';",
|
||||||
"export default from 'path';",
|
"export default from 'path';",
|
||||||
"export { A }, B from 'path';",
|
"export { A }, B from 'path';",
|
||||||
"export * as A, B from 'path';",
|
"export * as A, B from 'path';",
|
||||||
@@ -68,4 +73,109 @@ describe("export", function() {
|
|||||||
}, code);
|
}, code);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
it("Should reject `export` statement not under top-level scope", function() {
|
||||||
|
[
|
||||||
|
"{ export {}; }",
|
||||||
|
"if (0) export var A;",
|
||||||
|
"function f() { export default 42; }",
|
||||||
|
].forEach(function(code) {
|
||||||
|
assert.throws(function() {
|
||||||
|
UglifyJS.parse(code);
|
||||||
|
}, function(e) {
|
||||||
|
return e instanceof UglifyJS.JS_Parse_Error;
|
||||||
|
}, code);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should compare `export` statements correctly", function() {
|
||||||
|
var stats = {
|
||||||
|
Declaration: [
|
||||||
|
"export let A;",
|
||||||
|
"export const A = 42;",
|
||||||
|
"export var { A, B: [] } = C;",
|
||||||
|
"export function A() { return B(A); }",
|
||||||
|
"export async function* A({}, ...[]) { return B(A); }",
|
||||||
|
],
|
||||||
|
Default: [
|
||||||
|
"export default 42;",
|
||||||
|
"export default A => A(B);",
|
||||||
|
"export default class A extends B {}",
|
||||||
|
"export default (class A extends B {});",
|
||||||
|
"export default class A { static C = 42; }",
|
||||||
|
"export default class A extends B { static C = 42; }",
|
||||||
|
],
|
||||||
|
Foreign: [
|
||||||
|
"export * from 'path';",
|
||||||
|
"export {} from 'path';",
|
||||||
|
"export * as A from 'path';",
|
||||||
|
"export { default } from 'path';",
|
||||||
|
"export { A, B as C } from 'path';",
|
||||||
|
"export { A, default as C } from 'path';",
|
||||||
|
],
|
||||||
|
References: [
|
||||||
|
"export {};",
|
||||||
|
"export { A };",
|
||||||
|
"export { A as B };",
|
||||||
|
"export { A, B as C };",
|
||||||
|
"export { A as default };",
|
||||||
|
],
|
||||||
|
};
|
||||||
|
for (var k in stats) stats[k].forEach(function(c, i) {
|
||||||
|
var s = UglifyJS.parse(c);
|
||||||
|
assert.ok(s instanceof UglifyJS.AST_Toplevel, c);
|
||||||
|
assert.strictEqual(s.body.length, 1, c);
|
||||||
|
assert.strictEqual(s.body[0].TYPE, "Export" + k, c);
|
||||||
|
for (var l in stats) stats[l].forEach(function(d, j) {
|
||||||
|
var t = UglifyJS.parse(d);
|
||||||
|
assert.ok(t instanceof UglifyJS.AST_Toplevel, d);
|
||||||
|
assert.strictEqual(t.body.length, 1, d);
|
||||||
|
assert.strictEqual(t.body[0].TYPE, "Export" + l, d);
|
||||||
|
assert.strictEqual(s.equals(t), k === l && i === j, c + "\n" + d);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should interoperate with ESTree correctly", function() {
|
||||||
|
[
|
||||||
|
"export var A = 42;",
|
||||||
|
"export default (class A {});",
|
||||||
|
"var A; export { A as '42' };",
|
||||||
|
"export { '42' } from 'path';",
|
||||||
|
"export * as '42' from 'path';",
|
||||||
|
].forEach(function(code) {
|
||||||
|
var ast = UglifyJS.parse(code);
|
||||||
|
try {
|
||||||
|
var spidermonkey = ast.to_mozilla_ast();
|
||||||
|
} catch (ex) {
|
||||||
|
assert.fail("[to_mozilla_ast] " + ex.stack);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
var ast2 = UglifyJS.AST_Node.from_mozilla_ast(spidermonkey);
|
||||||
|
} catch (ex) {
|
||||||
|
assert.fail("[from_mozilla_ast] " + ex.stack);
|
||||||
|
}
|
||||||
|
assert.strictEqual(ast2.print_to_string(), ast.print_to_string(), [
|
||||||
|
"spidermonkey:",
|
||||||
|
ast.print_to_string(),
|
||||||
|
ast2.print_to_string(),
|
||||||
|
].join("\n"));
|
||||||
|
try {
|
||||||
|
var acorn_est = acorn.parse(code, {
|
||||||
|
ecmaVersion: "latest",
|
||||||
|
locations: true,
|
||||||
|
sourceType: "module",
|
||||||
|
});
|
||||||
|
} catch (ex) {
|
||||||
|
assert.fail("[acorn.parse] " + ex.stack);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
var ast3 = UglifyJS.AST_Node.from_mozilla_ast(acorn_est);
|
||||||
|
} catch (ex) {
|
||||||
|
assert.fail("[from_acorn] " + ex.stack);
|
||||||
|
}
|
||||||
|
assert.strictEqual(ast3.print_to_string(), ast.print_to_string(), [
|
||||||
|
"acorn:",
|
||||||
|
ast.print_to_string(),
|
||||||
|
ast3.print_to_string(),
|
||||||
|
].join("\n"));
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
var acorn = require("acorn");
|
||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
var UglifyJS = require("../node");
|
var UglifyJS = require("../node");
|
||||||
|
|
||||||
@@ -8,15 +9,25 @@ describe("import", function() {
|
|||||||
"import A;",
|
"import A;",
|
||||||
"import {};",
|
"import {};",
|
||||||
"import `path`;",
|
"import `path`;",
|
||||||
|
"{ import 'path'; }",
|
||||||
"import from 'path';",
|
"import from 'path';",
|
||||||
|
"if (0) import 'path';",
|
||||||
"import * from 'path';",
|
"import * from 'path';",
|
||||||
|
"import 'A' from 'path';",
|
||||||
|
"import A-B from 'path';",
|
||||||
"import A as B from 'path';",
|
"import A as B from 'path';",
|
||||||
"import { A }, B from 'path';",
|
"import { A }, B from 'path';",
|
||||||
|
"import * as 'A' from 'path';",
|
||||||
|
"import * as A-B from 'path';",
|
||||||
"import * as A, B from 'path';",
|
"import * as A, B from 'path';",
|
||||||
"import * as A, {} from 'path';",
|
"import * as A, {} from 'path';",
|
||||||
"import { * as A } from 'path';",
|
"import { * as A } from 'path';",
|
||||||
|
"import { * as 'A' } from 'path';",
|
||||||
|
"import { * as A-B } from 'path';",
|
||||||
|
"function f() { import 'path'; }",
|
||||||
"import { 42 as A } from 'path';",
|
"import { 42 as A } from 'path';",
|
||||||
"import { A-B as C } from 'path';",
|
"import { A-B as C } from 'path';",
|
||||||
|
"import { 'A' as 'B' } from 'path';",
|
||||||
].forEach(function(code) {
|
].forEach(function(code) {
|
||||||
assert.throws(function() {
|
assert.throws(function() {
|
||||||
UglifyJS.parse(code);
|
UglifyJS.parse(code);
|
||||||
@@ -25,4 +36,74 @@ describe("import", function() {
|
|||||||
}, code);
|
}, code);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
it("Should compare `import` statements correctly", function() {
|
||||||
|
[
|
||||||
|
"import 'foo';",
|
||||||
|
"import 'path';",
|
||||||
|
"import A from 'path';",
|
||||||
|
"import { A } from 'path';",
|
||||||
|
"import * as A from 'path';",
|
||||||
|
"import A, { B } from 'path';",
|
||||||
|
"import A, * as B from 'path';",
|
||||||
|
"import { A as B } from 'path';",
|
||||||
|
"import A, { B, C as D } from 'path';",
|
||||||
|
].forEach(function(c, i, stats) {
|
||||||
|
var s = UglifyJS.parse(c);
|
||||||
|
assert.ok(s instanceof UglifyJS.AST_Toplevel, c);
|
||||||
|
assert.strictEqual(s.body.length, 1, c);
|
||||||
|
assert.ok(s.body[0] instanceof UglifyJS.AST_Import, c);
|
||||||
|
stats.forEach(function(d, j) {
|
||||||
|
var t = UglifyJS.parse(d);
|
||||||
|
assert.ok(t instanceof UglifyJS.AST_Toplevel, d);
|
||||||
|
assert.strictEqual(t.body.length, 1, d);
|
||||||
|
assert.ok(t.body[0] instanceof UglifyJS.AST_Import, d);
|
||||||
|
assert.strictEqual(s.equals(t), i === j, c + "\n" + d);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should interoperate with ESTree correctly", function() {
|
||||||
|
[
|
||||||
|
"import A from 'path';",
|
||||||
|
"import * as A from 'path';",
|
||||||
|
"import A, * as B from 'path';",
|
||||||
|
"import { '42' as A, B } from 'path';",
|
||||||
|
"import A, { '42' as B } from 'path';",
|
||||||
|
].forEach(function(code) {
|
||||||
|
var ast = UglifyJS.parse(code);
|
||||||
|
try {
|
||||||
|
var spidermonkey = ast.to_mozilla_ast();
|
||||||
|
} catch (ex) {
|
||||||
|
assert.fail("[to_mozilla_ast] " + ex.stack);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
var ast2 = UglifyJS.AST_Node.from_mozilla_ast(spidermonkey);
|
||||||
|
} catch (ex) {
|
||||||
|
assert.fail("[from_mozilla_ast] " + ex.stack);
|
||||||
|
}
|
||||||
|
assert.strictEqual(ast2.print_to_string(), ast.print_to_string(), [
|
||||||
|
"spidermonkey:",
|
||||||
|
ast.print_to_string(),
|
||||||
|
ast2.print_to_string(),
|
||||||
|
].join("\n"));
|
||||||
|
try {
|
||||||
|
var acorn_est = acorn.parse(code, {
|
||||||
|
ecmaVersion: "latest",
|
||||||
|
locations: true,
|
||||||
|
sourceType: "module",
|
||||||
|
});
|
||||||
|
} catch (ex) {
|
||||||
|
assert.fail("[acorn.parse] " + ex.stack);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
var ast3 = UglifyJS.AST_Node.from_mozilla_ast(acorn_est);
|
||||||
|
} catch (ex) {
|
||||||
|
assert.fail("[from_acorn] " + ex.stack);
|
||||||
|
}
|
||||||
|
assert.strictEqual(ast3.print_to_string(), ast.print_to_string(), [
|
||||||
|
"acorn:",
|
||||||
|
ast.print_to_string(),
|
||||||
|
ast3.print_to_string(),
|
||||||
|
].join("\n"));
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
var readFileSync = require("fs").readFileSync;
|
var readFileSync = require("fs").readFileSync;
|
||||||
var run_code = require("../sandbox").run_code;
|
var run_code = require("../sandbox").run_code;
|
||||||
|
var semver = require("semver");
|
||||||
var UglifyJS = require("../..");
|
var UglifyJS = require("../..");
|
||||||
|
|
||||||
function read(path) {
|
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() {
|
describe("rename", function() {
|
||||||
it("Should be repeatable", function() {
|
it("Should be repeatable", function() {
|
||||||
var code = "!function(x){return x(x)}(y);";
|
var code = "!function(x){return x(x)}(y);";
|
||||||
|
|||||||
@@ -9,19 +9,22 @@ function beautify(ast) {
|
|||||||
var beautified = UglifyJS.minify(ast, {
|
var beautified = UglifyJS.minify(ast, {
|
||||||
compress: false,
|
compress: false,
|
||||||
mangle: false,
|
mangle: false,
|
||||||
|
module: ufuzz.module,
|
||||||
output: {
|
output: {
|
||||||
|
ast: true,
|
||||||
beautify: true,
|
beautify: true,
|
||||||
braces: true,
|
braces: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (beautified.error) return beautified;
|
if (!beautified.error) {
|
||||||
return UglifyJS.minify(beautified.code, {
|
var verify = UglifyJS.minify(beautified.code, {
|
||||||
compress: false,
|
compress: false,
|
||||||
mangle: false,
|
mangle: false,
|
||||||
output: {
|
module: ufuzz.module,
|
||||||
ast: true,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
if (verify.error) return verify;
|
||||||
|
}
|
||||||
|
return beautified;
|
||||||
}
|
}
|
||||||
|
|
||||||
function validate(ast) {
|
function validate(ast) {
|
||||||
@@ -35,6 +38,7 @@ function validate(ast) {
|
|||||||
return UglifyJS.minify(ast, {
|
return UglifyJS.minify(ast, {
|
||||||
compress: false,
|
compress: false,
|
||||||
mangle: false,
|
mangle: false,
|
||||||
|
module: ufuzz.module,
|
||||||
output: {
|
output: {
|
||||||
ast: true,
|
ast: true,
|
||||||
},
|
},
|
||||||
@@ -57,12 +61,12 @@ function test(input, to_moz, description, skip_on_error, beautified) {
|
|||||||
var ast = UglifyJS.AST_Node.from_mozilla_ast(to_moz(input));
|
var ast = UglifyJS.AST_Node.from_mozilla_ast(to_moz(input));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (skip_on_error) return true;
|
if (skip_on_error) return true;
|
||||||
console.log("//=============================================================");
|
console.error("//=============================================================");
|
||||||
console.log("//", description, "failed... round", round);
|
console.error("//", description, "failed... round", round);
|
||||||
console.log(e);
|
console.error(e);
|
||||||
console.log("// original code");
|
console.error("// original code");
|
||||||
if (beautified === true) console.log("// (beautified)");
|
if (beautified === true) console.error("// (beautified)");
|
||||||
console.log(input.code);
|
console.error(input.code);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
var transformed = validate(ast);
|
var transformed = validate(ast);
|
||||||
@@ -74,34 +78,34 @@ function test(input, to_moz, description, skip_on_error, beautified) {
|
|||||||
if (!test(beautified, to_moz, description, skip_on_error, true)) return false;
|
if (!test(beautified, to_moz, description, skip_on_error, true)) return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log("//=============================================================");
|
console.error("//=============================================================");
|
||||||
console.log("// !!!!!! Failed... round", round);
|
console.error("// !!!!!! Failed... round", round);
|
||||||
console.log("// original code");
|
console.error("// original code");
|
||||||
if (beautified.error) {
|
if (beautified.error) {
|
||||||
console.log("// !!! beautify failed !!!");
|
console.error("// !!! beautify failed !!!");
|
||||||
console.log(beautified.error.stack);
|
console.error(beautified.error.stack);
|
||||||
} else if (beautified === true) {
|
} else if (beautified === true) {
|
||||||
console.log("// (beautified)");
|
console.error("// (beautified)");
|
||||||
}
|
}
|
||||||
console.log(input.raw);
|
console.error(input.raw);
|
||||||
console.log();
|
console.error();
|
||||||
console.log();
|
console.error();
|
||||||
console.log("//-------------------------------------------------------------");
|
console.error("//-------------------------------------------------------------");
|
||||||
console.log("//", description);
|
console.error("//", description);
|
||||||
if (transformed.error) {
|
if (transformed.error) {
|
||||||
console.log(transformed.error.stack);
|
console.error(transformed.error.stack);
|
||||||
} else {
|
} else {
|
||||||
beautified = beautify(transformed.ast);
|
beautified = beautify(transformed.ast);
|
||||||
if (beautified.error) {
|
if (beautified.error) {
|
||||||
console.log("// !!! beautify failed !!!");
|
console.error("// !!! beautify failed !!!");
|
||||||
console.log(beautified.error.stack);
|
console.error(beautified.error.stack);
|
||||||
console.log(transformed.code);
|
console.error(transformed.code);
|
||||||
} else {
|
} else {
|
||||||
console.log("// (beautified)");
|
console.error("// (beautified)");
|
||||||
console.log(beautified.code);
|
console.error(beautified.code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log("!!!!!! Failed... round", round);
|
console.error("!!!!!! Failed... round", round);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -115,9 +119,29 @@ for (var round = 1; round <= num_iterations; round++) {
|
|||||||
var code = ufuzz.createTopLevelCode();
|
var code = ufuzz.createTopLevelCode();
|
||||||
minify_options.forEach(function(options) {
|
minify_options.forEach(function(options) {
|
||||||
var ok = true;
|
var ok = true;
|
||||||
var input = UglifyJS.minify(options ? UglifyJS.minify(code, JSON.parse(options)).code : code, {
|
var minified;
|
||||||
|
if (options) {
|
||||||
|
var o = JSON.parse(options);
|
||||||
|
o.module = ufuzz.module;
|
||||||
|
minified = UglifyJS.minify(code, o);
|
||||||
|
if (minified.error) {
|
||||||
|
console.log("//=============================================================");
|
||||||
|
console.log("// minify() failed... round", round);
|
||||||
|
console.log("// original code");
|
||||||
|
console.log(code);
|
||||||
|
console.log();
|
||||||
|
console.log();
|
||||||
|
console.log("//-------------------------------------------------------------");
|
||||||
|
console.log("minify(options):");
|
||||||
|
console.log(JSON.stringify(o, null, 2));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
minified = minified.code;
|
||||||
|
}
|
||||||
|
var input = UglifyJS.minify(minified || code, {
|
||||||
compress: false,
|
compress: false,
|
||||||
mangle: false,
|
mangle: false,
|
||||||
|
module: ufuzz.module,
|
||||||
output: {
|
output: {
|
||||||
ast: true,
|
ast: true,
|
||||||
},
|
},
|
||||||
@@ -125,11 +149,27 @@ for (var round = 1; round <= num_iterations; round++) {
|
|||||||
input.raw = options ? input.code : code;
|
input.raw = options ? input.code : code;
|
||||||
if (input.error) {
|
if (input.error) {
|
||||||
ok = false;
|
ok = false;
|
||||||
console.log("//=============================================================");
|
console.error("//=============================================================");
|
||||||
console.log("// minify() failed... round", round);
|
console.error("// parse() failed... round", round);
|
||||||
console.log(input.error);
|
console.error("// original code");
|
||||||
console.log("// original code");
|
console.error(code);
|
||||||
console.log(code);
|
console.error();
|
||||||
|
console.error();
|
||||||
|
if (options) {
|
||||||
|
console.error("//-------------------------------------------------------------");
|
||||||
|
console.error("// minified code");
|
||||||
|
console.error(minified);
|
||||||
|
console.error();
|
||||||
|
console.error();
|
||||||
|
console.error("//-------------------------------------------------------------");
|
||||||
|
console.error("minify(options):");
|
||||||
|
console.error(JSON.stringify(o, null, 2));
|
||||||
|
console.error();
|
||||||
|
console.error();
|
||||||
|
}
|
||||||
|
console.error("//-------------------------------------------------------------");
|
||||||
|
console.error("// parse() error");
|
||||||
|
console.error(input.error);
|
||||||
}
|
}
|
||||||
if (ok) ok = test(input, function(input) {
|
if (ok) ok = test(input, function(input) {
|
||||||
return input.ast.to_mozilla_ast();
|
return input.ast.to_mozilla_ast();
|
||||||
@@ -141,7 +181,10 @@ for (var round = 1; round <= num_iterations; round++) {
|
|||||||
sourceType: "module",
|
sourceType: "module",
|
||||||
});
|
});
|
||||||
}, "acorn.parse()", !ufuzz.verbose);
|
}, "acorn.parse()", !ufuzz.verbose);
|
||||||
if (!ok) process.exit(1);
|
if (!ok && isFinite(num_iterations)) {
|
||||||
|
console.log();
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
console.log();
|
console.log();
|
||||||
|
|||||||
@@ -241,23 +241,6 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
return node.name;
|
return node.name;
|
||||||
}
|
}
|
||||||
else if (node instanceof U.AST_DestructuredArray) {
|
|
||||||
var expr = node.elements[0];
|
|
||||||
if (expr && !(expr instanceof U.AST_Hole)) {
|
|
||||||
node.start._permute++;
|
|
||||||
CHANGED = true;
|
|
||||||
return expr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (node instanceof U.AST_DestructuredObject) {
|
|
||||||
// first property's value
|
|
||||||
var expr = node.properties[0];
|
|
||||||
if (expr) {
|
|
||||||
node.start._permute++;
|
|
||||||
CHANGED = true;
|
|
||||||
return expr.value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (node instanceof U.AST_Defun) {
|
else if (node instanceof U.AST_Defun) {
|
||||||
switch (((node.start._permute += step) * steps | 0) % 2) {
|
switch (((node.start._permute += step) * steps | 0) % 2) {
|
||||||
case 0:
|
case 0:
|
||||||
@@ -275,6 +258,23 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (node instanceof U.AST_DestructuredArray) {
|
||||||
|
var expr = node.elements[0];
|
||||||
|
if (expr && !(expr instanceof U.AST_Hole)) {
|
||||||
|
node.start._permute++;
|
||||||
|
CHANGED = true;
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (node instanceof U.AST_DestructuredObject) {
|
||||||
|
// first property's value
|
||||||
|
var expr = node.properties[0];
|
||||||
|
if (expr) {
|
||||||
|
node.start._permute++;
|
||||||
|
CHANGED = true;
|
||||||
|
return expr.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (node instanceof U.AST_DWLoop) {
|
else if (node instanceof U.AST_DWLoop) {
|
||||||
var expr = [
|
var expr = [
|
||||||
node.condition,
|
node.condition,
|
||||||
@@ -296,6 +296,16 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
return to_statement(expr);
|
return to_statement(expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (node instanceof U.AST_ExportDeclaration) {
|
||||||
|
node.start._permute++;
|
||||||
|
CHANGED = true;
|
||||||
|
return node.body;
|
||||||
|
}
|
||||||
|
else if (node instanceof U.AST_ExportDefault) {
|
||||||
|
node.start._permute++;
|
||||||
|
CHANGED = true;
|
||||||
|
return to_statement(node.body);
|
||||||
|
}
|
||||||
else if (node instanceof U.AST_Finally) {
|
else if (node instanceof U.AST_Finally) {
|
||||||
// drop finally block
|
// drop finally block
|
||||||
node.start._permute++;
|
node.start._permute++;
|
||||||
@@ -351,6 +361,15 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
return to_statement(expr);
|
return to_statement(expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (node instanceof U.AST_LabeledStatement) {
|
||||||
|
if (node.body instanceof U.AST_Statement
|
||||||
|
&& !has_loopcontrol(node.body, node.body, node)) {
|
||||||
|
// replace labelled statement with its non-labelled body
|
||||||
|
node.start._permute = REPLACEMENTS.length;
|
||||||
|
CHANGED = true;
|
||||||
|
return node.body;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (node instanceof U.AST_Object) {
|
else if (node instanceof U.AST_Object) {
|
||||||
// first property's value
|
// first property's value
|
||||||
var expr = node.properties[0];
|
var expr = node.properties[0];
|
||||||
@@ -441,13 +460,14 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
return to_statement(node.definitions[0].value);
|
return to_statement(node.definitions[0].value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (node instanceof U.AST_LabeledStatement) {
|
else if (node instanceof U.AST_VarDef) {
|
||||||
if (node.body instanceof U.AST_Statement
|
if (node.value) {
|
||||||
&& !has_loopcontrol(node.body, node.body, node)) {
|
node.start._permute++;
|
||||||
// replace labelled statement with its non-labelled body
|
|
||||||
node.start._permute = REPLACEMENTS.length;
|
|
||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
return node.body;
|
return new U.AST_VarDef({
|
||||||
|
name: node.name,
|
||||||
|
start: {},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -760,9 +780,9 @@ function compare_run_code(code, minify_options, result_cache, max_timeout) {
|
|||||||
if (minified.error) return minified;
|
if (minified.error) return minified;
|
||||||
|
|
||||||
var toplevel = sandbox.has_toplevel(minify_options);
|
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 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)) {
|
if (sandbox.same_stdout(unminified.result, minified_result)) {
|
||||||
return is_timed_out(unminified.result) && is_timed_out(minified_result) && {
|
return is_timed_out(unminified.result) && is_timed_out(minified_result) && {
|
||||||
@@ -774,6 +794,16 @@ function compare_run_code(code, minify_options, result_cache, max_timeout) {
|
|||||||
minified_result: minified_result,
|
minified_result: minified_result,
|
||||||
elapsed: unminified.elapsed,
|
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) {
|
function test_minify(code, minify_options) {
|
||||||
|
|||||||
@@ -140,6 +140,7 @@ var SUPPORT = function(matrix) {
|
|||||||
class: "class C { f() {} }",
|
class: "class C { f() {} }",
|
||||||
class_field: "class C { p = 0; }",
|
class_field: "class C { p = 0; }",
|
||||||
class_private: "class C { #f() {} }",
|
class_private: "class C { #f() {} }",
|
||||||
|
class_static_init: "class C { static {} }",
|
||||||
computed_key: "({[0]: 0});",
|
computed_key: "({[0]: 0});",
|
||||||
const_block: "var a; { const a = 0; }",
|
const_block: "var a; { const a = 0; }",
|
||||||
default_value: "[ a = 0 ] = [];",
|
default_value: "[ a = 0 ] = [];",
|
||||||
@@ -252,7 +253,7 @@ BINARY_OPS = BINARY_OPS.concat(BINARY_OPS);
|
|||||||
if (SUPPORT.exponentiation) BINARY_OPS.push("**");
|
if (SUPPORT.exponentiation) BINARY_OPS.push("**");
|
||||||
BINARY_OPS = BINARY_OPS.concat(BINARY_OPS);
|
BINARY_OPS = BINARY_OPS.concat(BINARY_OPS);
|
||||||
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 = [ "=" ];
|
var ASSIGNMENTS = [ "=" ];
|
||||||
ASSIGNMENTS = ASSIGNMENTS.concat(ASSIGNMENTS);
|
ASSIGNMENTS = ASSIGNMENTS.concat(ASSIGNMENTS);
|
||||||
@@ -405,7 +406,7 @@ function createTopLevelCode() {
|
|||||||
unique_vars.length = 0;
|
unique_vars.length = 0;
|
||||||
classes.length = 0;
|
classes.length = 0;
|
||||||
allow_this = true;
|
allow_this = true;
|
||||||
async = false;
|
async = SUPPORT.async && rng(200) == 0;
|
||||||
has_await = false;
|
has_await = false;
|
||||||
export_default = false;
|
export_default = false;
|
||||||
generator = false;
|
generator = false;
|
||||||
@@ -413,7 +414,7 @@ function createTopLevelCode() {
|
|||||||
funcs = 0;
|
funcs = 0;
|
||||||
clazz = 0;
|
clazz = 0;
|
||||||
imports = 0;
|
imports = 0;
|
||||||
in_class = 0;
|
in_class = async;
|
||||||
called = Object.create(null);
|
called = Object.create(null);
|
||||||
var s = [
|
var s = [
|
||||||
strictMode(),
|
strictMode(),
|
||||||
@@ -1181,7 +1182,11 @@ function createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn
|
|||||||
unique_vars.length = unique_len;
|
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;
|
return s;
|
||||||
case STMT_C:
|
case STMT_C:
|
||||||
return "c = c + 1;";
|
return "c = c + 1;";
|
||||||
@@ -1839,6 +1844,16 @@ function createClassLiteral(recurmax, stmtDepth, canThrow, name) {
|
|||||||
async = save_async;
|
async = save_async;
|
||||||
}
|
}
|
||||||
s += ";\n";
|
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 {
|
} else {
|
||||||
if (!fixed && !internal && constructor && rng(10) == 0) {
|
if (!fixed && !internal && constructor && rng(10) == 0) {
|
||||||
internal = constructor;
|
internal = constructor;
|
||||||
@@ -1994,7 +2009,7 @@ function createBinaryOp(noComma, canThrow) {
|
|||||||
var op;
|
var op;
|
||||||
do {
|
do {
|
||||||
op = BINARY_OPS[rng(BINARY_OPS.length)];
|
op = BINARY_OPS[rng(BINARY_OPS.length)];
|
||||||
} while (noComma && op == "," || !canThrow && op == " in ");
|
} while (noComma && op == "," || !canThrow && /^ in/.test(op));
|
||||||
return op;
|
return op;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2080,13 +2095,23 @@ function createVarName(maybe, dontStore) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (require.main !== module) {
|
if (require.main !== module) {
|
||||||
exports.createTopLevelCode = createTopLevelCode;
|
exports.createTopLevelCode = function() {
|
||||||
|
var code = createTopLevelCode();
|
||||||
|
exports.module = async && has_await;
|
||||||
|
return code;
|
||||||
|
};
|
||||||
exports.num_iterations = num_iterations;
|
exports.num_iterations = num_iterations;
|
||||||
exports.verbose = verbose;
|
exports.verbose = verbose;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
function run_code(code, toplevel, timeout) {
|
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);
|
return sandbox.run_code(sandbox.patch_module_statements(code), toplevel, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2106,7 +2131,9 @@ function errorln(msg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function try_beautify(code, toplevel, result, printfn, options) {
|
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) {
|
if (beautified.error) {
|
||||||
printfn("// !!! beautify failed !!!");
|
printfn("// !!! beautify failed !!!");
|
||||||
printfn(beautified.error);
|
printfn(beautified.error);
|
||||||
@@ -2259,12 +2286,27 @@ function log(options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function sort_globals(code) {
|
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 function(m, n) {
|
||||||
return (typeof global[n] == "function") - (typeof global[m] == "function")
|
return (typeof global[n] == "function") - (typeof global[m] == "function")
|
||||||
|| (m < n ? -1 : m > n ? 1 : 0);
|
|| (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)) {
|
if (!Array.isArray(globals)) {
|
||||||
errorln();
|
errorln();
|
||||||
errorln();
|
errorln();
|
||||||
@@ -2466,6 +2508,9 @@ var bug_class_static_await = SUPPORT.async && SUPPORT.class_field && sandbox.is_
|
|||||||
var bug_class_static_nontrivial = SUPPORT.class_field && sandbox.is_error(sandbox.run_code("class A { static 42; static get 42() {} }"));
|
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_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_for_of_var = SUPPORT.for_of && SUPPORT.let && sandbox.is_error(sandbox.run_code("try {} catch (e) { for (var e of []); }"));
|
||||||
|
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);"))) {
|
if (SUPPORT.destructuring && sandbox.is_error(sandbox.run_code("console.log([ 1 ], {} = 2);"))) {
|
||||||
beautify_options.output.v8 = true;
|
beautify_options.output.v8 = true;
|
||||||
minify_options.forEach(function(o) {
|
minify_options.forEach(function(o) {
|
||||||
@@ -2496,11 +2541,17 @@ for (var round = 1; round <= num_iterations; round++) {
|
|||||||
println();
|
println();
|
||||||
// ignore v8 parser bug
|
// ignore v8 parser bug
|
||||||
return bug_async_arrow_rest(result)
|
return bug_async_arrow_rest(result)
|
||||||
|
// ignore Node.js `__proto__` quirks
|
||||||
|
|| bug_proto_stream(result)
|
||||||
// ignore runtime platform bugs
|
// ignore runtime platform bugs
|
||||||
|| result.message == "Script execution aborted.";
|
|| result.message == "Script execution aborted.";
|
||||||
})) continue;
|
})) continue;
|
||||||
minify_options.forEach(function(options) {
|
minify_options.forEach(function(options) {
|
||||||
var o = JSON.parse(options);
|
var o = JSON.parse(options);
|
||||||
|
if (async && has_await) {
|
||||||
|
o.module = true;
|
||||||
|
options = JSON.stringify(o);
|
||||||
|
}
|
||||||
var toplevel = sandbox.has_toplevel(o);
|
var toplevel = sandbox.has_toplevel(o);
|
||||||
o.validate = true;
|
o.validate = true;
|
||||||
uglify_code = UglifyJS.minify(original_code, o);
|
uglify_code = UglifyJS.minify(original_code, o);
|
||||||
@@ -2513,6 +2564,8 @@ for (var round = 1; round <= num_iterations; round++) {
|
|||||||
var uglify_erred = sandbox.is_error(uglify_result);
|
var uglify_erred = sandbox.is_error(uglify_result);
|
||||||
// ignore v8 parser bug
|
// ignore v8 parser bug
|
||||||
if (!ok && uglify_erred && bug_async_arrow_rest(uglify_result)) ok = true;
|
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
|
// ignore runtime platform bugs
|
||||||
if (!ok && uglify_erred && uglify_result.message == "Script execution aborted.") ok = true;
|
if (!ok && uglify_erred && uglify_result.message == "Script execution aborted.") ok = true;
|
||||||
// handle difference caused by time-outs
|
// handle difference caused by time-outs
|
||||||
|
|||||||
Reference in New Issue
Block a user