@@ -551,7 +551,7 @@ function is_function(node) {
|
|||||||
return node instanceof AST_AsyncFunction || node instanceof AST_Function;
|
return node instanceof AST_AsyncFunction || node instanceof AST_Function;
|
||||||
}
|
}
|
||||||
|
|
||||||
var AST_AsyncFunction = DEFNODE("AsyncFunction", null, {
|
var AST_AsyncFunction = DEFNODE("AsyncFunction", "inlined", {
|
||||||
$documentation: "An asynchronous function expression",
|
$documentation: "An asynchronous function expression",
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
if (this.name != null) {
|
if (this.name != null) {
|
||||||
@@ -573,7 +573,7 @@ function is_defun(node) {
|
|||||||
return node instanceof AST_AsyncDefun || node instanceof AST_Defun;
|
return node instanceof AST_AsyncDefun || node instanceof AST_Defun;
|
||||||
}
|
}
|
||||||
|
|
||||||
var AST_AsyncDefun = DEFNODE("AsyncDefun", null, {
|
var AST_AsyncDefun = DEFNODE("AsyncDefun", "inlined", {
|
||||||
$documentation: "An asynchronous function definition",
|
$documentation: "An asynchronous function definition",
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
if (!(this.name instanceof AST_SymbolDefun)) throw new Error("name must be AST_SymbolDefun");
|
if (!(this.name instanceof AST_SymbolDefun)) throw new Error("name must be AST_SymbolDefun");
|
||||||
|
|||||||
@@ -927,6 +927,7 @@ merge(Compressor.prototype, {
|
|||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
def(AST_Lambda, function(tw, descend, compressor) {
|
def(AST_Lambda, function(tw, descend, compressor) {
|
||||||
|
this.inlined = false;
|
||||||
push(tw);
|
push(tw);
|
||||||
reset_variables(tw, compressor, this);
|
reset_variables(tw, compressor, this);
|
||||||
descend();
|
descend();
|
||||||
@@ -1630,7 +1631,7 @@ merge(Compressor.prototype, {
|
|||||||
var assign_used = false;
|
var assign_used = false;
|
||||||
var can_replace = !args || !hit;
|
var can_replace = !args || !hit;
|
||||||
if (!can_replace) {
|
if (!can_replace) {
|
||||||
for (var j = compressor.self().argnames.lastIndexOf(candidate.name) + 1; !abort && j < args.length; j++) {
|
for (var j = scope.argnames.lastIndexOf(candidate.name) + 1; !abort && j < args.length; j++) {
|
||||||
args[j].transform(scanner);
|
args[j].transform(scanner);
|
||||||
}
|
}
|
||||||
can_replace = true;
|
can_replace = true;
|
||||||
@@ -1819,7 +1820,7 @@ merge(Compressor.prototype, {
|
|||||||
|
|
||||||
function extract_args() {
|
function extract_args() {
|
||||||
var iife, fn = compressor.self();
|
var iife, fn = compressor.self();
|
||||||
if (fn instanceof AST_Function
|
if (is_function(fn)
|
||||||
&& !fn.name
|
&& !fn.name
|
||||||
&& !fn.uses_arguments
|
&& !fn.uses_arguments
|
||||||
&& !fn.pinned()
|
&& !fn.pinned()
|
||||||
@@ -1830,6 +1831,29 @@ merge(Compressor.prototype, {
|
|||||||
})) {
|
})) {
|
||||||
var fn_strict = compressor.has_directive("use strict");
|
var fn_strict = compressor.has_directive("use strict");
|
||||||
if (fn_strict && !member(fn_strict, fn.body)) fn_strict = false;
|
if (fn_strict && !member(fn_strict, fn.body)) fn_strict = false;
|
||||||
|
var has_await = fn instanceof AST_AsyncFunction ? function(node) {
|
||||||
|
return node instanceof AST_Symbol && node.name == "await";
|
||||||
|
} : function(node) {
|
||||||
|
return node instanceof AST_Await && !tw.find_parent(AST_Scope);
|
||||||
|
};
|
||||||
|
var tw = new TreeWalker(function(node) {
|
||||||
|
if (!arg) return true;
|
||||||
|
if (has_await(node)) {
|
||||||
|
arg = null;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (node instanceof AST_SymbolRef && fn.variables.has(node.name)) {
|
||||||
|
var s = node.definition().scope;
|
||||||
|
if (s !== scope) while (s = s.parent_scope) {
|
||||||
|
if (s === scope) return true;
|
||||||
|
}
|
||||||
|
arg = null;
|
||||||
|
}
|
||||||
|
if (node instanceof AST_This && (fn_strict || !tw.find_parent(AST_Scope))) {
|
||||||
|
arg = null;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
var len = fn.argnames.length;
|
var len = fn.argnames.length;
|
||||||
args = iife.args.slice(len);
|
args = iife.args.slice(len);
|
||||||
var names = Object.create(null);
|
var names = Object.create(null);
|
||||||
@@ -1852,20 +1876,7 @@ merge(Compressor.prototype, {
|
|||||||
} else if (arg instanceof AST_Lambda && arg.pinned()) {
|
} else if (arg instanceof AST_Lambda && arg.pinned()) {
|
||||||
arg = null;
|
arg = null;
|
||||||
} else {
|
} else {
|
||||||
arg.walk(new TreeWalker(function(node) {
|
arg.walk(tw);
|
||||||
if (!arg) return true;
|
|
||||||
if (node instanceof AST_SymbolRef && fn.variables.has(node.name)) {
|
|
||||||
var s = node.definition().scope;
|
|
||||||
if (s !== scope) while (s = s.parent_scope) {
|
|
||||||
if (s === scope) return true;
|
|
||||||
}
|
|
||||||
arg = null;
|
|
||||||
}
|
|
||||||
if (node instanceof AST_This && (fn_strict || !this.find_parent(AST_Scope))) {
|
|
||||||
arg = null;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
if (arg) candidates.unshift([ make_node(AST_VarDef, sym, {
|
if (arg) candidates.unshift([ make_node(AST_VarDef, sym, {
|
||||||
name: sym,
|
name: sym,
|
||||||
@@ -8982,7 +8993,7 @@ merge(Compressor.prototype, {
|
|||||||
single_use = fixed.is_constant_expression(self.scope);
|
single_use = fixed.is_constant_expression(self.scope);
|
||||||
if (single_use == "f") {
|
if (single_use == "f") {
|
||||||
var scope = self.scope;
|
var scope = self.scope;
|
||||||
do if (scope instanceof AST_Defun || scope instanceof AST_Function) {
|
do if (is_defun(scope) || is_function(scope)) {
|
||||||
scope.inlined = true;
|
scope.inlined = true;
|
||||||
} while (scope = scope.parent_scope);
|
} while (scope = scope.parent_scope);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1638,6 +1638,7 @@ function parse($TEXT, options) {
|
|||||||
function maybe_await() {
|
function maybe_await() {
|
||||||
var start = S.token;
|
var start = S.token;
|
||||||
if (!(S.in_async && is("name", "await"))) return maybe_unary();
|
if (!(S.in_async && is("name", "await"))) return maybe_unary();
|
||||||
|
S.input.context().regex_allowed = true;
|
||||||
next();
|
next();
|
||||||
return new AST_Await({
|
return new AST_Await({
|
||||||
start: start,
|
start: start,
|
||||||
|
|||||||
@@ -387,3 +387,60 @@ issue_4347_2: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
node_version: ">=8"
|
node_version: ">=8"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4349_1: {
|
||||||
|
input: {
|
||||||
|
console.log(typeof async function() {
|
||||||
|
await /abc/;
|
||||||
|
}().then);
|
||||||
|
}
|
||||||
|
expect_exact: "console.log(typeof async function(){await/abc/}().then);"
|
||||||
|
expect_stdout: "function"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4349_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(typeof async function() {
|
||||||
|
(function(a) {
|
||||||
|
this[a];
|
||||||
|
}(await 0));
|
||||||
|
}().then);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(typeof async function() {
|
||||||
|
(function(a) {
|
||||||
|
this[a];
|
||||||
|
}(await 0));
|
||||||
|
}().then);
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4349_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(typeof function(await) {
|
||||||
|
return async function(a) {
|
||||||
|
this[a];
|
||||||
|
}(await);
|
||||||
|
}(this).then);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(typeof function(await) {
|
||||||
|
return async function(a) {
|
||||||
|
this[a];
|
||||||
|
}(await);
|
||||||
|
}(this).then);
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user