@@ -578,6 +578,10 @@ var AST_Arrow = DEFNODE("Arrow", "inlined value", {
|
|||||||
},
|
},
|
||||||
}, AST_Lambda);
|
}, AST_Lambda);
|
||||||
|
|
||||||
|
function is_async(node) {
|
||||||
|
return node instanceof AST_AsyncDefun || node instanceof AST_AsyncFunction;
|
||||||
|
}
|
||||||
|
|
||||||
var AST_AsyncFunction = DEFNODE("AsyncFunction", "inlined name", {
|
var AST_AsyncFunction = DEFNODE("AsyncFunction", "inlined name", {
|
||||||
$documentation: "An asynchronous function expression",
|
$documentation: "An asynchronous function expression",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
|
|||||||
@@ -7772,7 +7772,7 @@ merge(Compressor.prototype, {
|
|||||||
});
|
});
|
||||||
if (can_inline && stat instanceof AST_Return) {
|
if (can_inline && stat instanceof AST_Return) {
|
||||||
var value = stat.value;
|
var value = stat.value;
|
||||||
if (exp === fn && (!value || value.is_constant_expression())) {
|
if (exp === fn && (!value || value.is_constant_expression() && safe_from_await(value))) {
|
||||||
var args = self.args.concat(value || make_node(AST_Undefined, self));
|
var args = self.args.concat(value || make_node(AST_Undefined, self));
|
||||||
return make_sequence(self, args).optimize(compressor);
|
return make_sequence(self, args).optimize(compressor);
|
||||||
}
|
}
|
||||||
@@ -7861,6 +7861,26 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
return try_evaluate(compressor, self);
|
return try_evaluate(compressor, self);
|
||||||
|
|
||||||
|
function safe_from_await(node) {
|
||||||
|
if (!is_async(scope || compressor.find_parent(AST_Scope))) return true;
|
||||||
|
var safe = true;
|
||||||
|
var tw = new TreeWalker(function(node) {
|
||||||
|
if (!safe) return true;
|
||||||
|
if (node instanceof AST_Scope) {
|
||||||
|
if (node === fn) return;
|
||||||
|
if (node instanceof AST_Arrow) {
|
||||||
|
for (var i = 0; safe && i < node.argnames.length; i++) node.argnames[i].walk(tw);
|
||||||
|
} else if (is_defun(node) && node.name.name == "await") {
|
||||||
|
safe = false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (node instanceof AST_Symbol && node.name == "await" && node !== fn.name) safe = false;
|
||||||
|
});
|
||||||
|
node.walk(tw);
|
||||||
|
return safe;
|
||||||
|
}
|
||||||
|
|
||||||
function return_value(stat) {
|
function return_value(stat) {
|
||||||
if (!stat) return make_node(AST_Undefined, self);
|
if (!stat) return make_node(AST_Undefined, self);
|
||||||
if (stat instanceof AST_Return) return stat.value || make_node(AST_Undefined, self);
|
if (stat instanceof AST_Return) return stat.value || make_node(AST_Undefined, self);
|
||||||
@@ -7927,8 +7947,7 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
if (node instanceof AST_Scope) return abort = true;
|
if (node instanceof AST_Scope) return abort = true;
|
||||||
if (verify_await && node instanceof AST_Symbol && node.name == "await") {
|
if (verify_await && node instanceof AST_Symbol && node.name == "await") {
|
||||||
var scope = compressor.find_parent(AST_Scope);
|
if (is_async(compressor.find_parent(AST_Scope))) return abort = true;
|
||||||
if (scope instanceof AST_AsyncDefun || scope instanceof AST_AsyncFunction) return abort = true;
|
|
||||||
verify_await = false;
|
verify_await = false;
|
||||||
}
|
}
|
||||||
if (node instanceof AST_SymbolRef) {
|
if (node instanceof AST_SymbolRef) {
|
||||||
@@ -8031,18 +8050,7 @@ merge(Compressor.prototype, {
|
|||||||
} while (!(scope instanceof AST_Scope));
|
} while (!(scope instanceof AST_Scope));
|
||||||
insert = scope.body.indexOf(child) + 1;
|
insert = scope.body.indexOf(child) + 1;
|
||||||
if (!insert) return false;
|
if (!insert) return false;
|
||||||
if (scope instanceof AST_AsyncDefun || scope instanceof AST_AsyncFunction) {
|
if (!safe_from_await(fn)) return false;
|
||||||
var found = false;
|
|
||||||
fn.walk(new TreeWalker(function(node) {
|
|
||||||
if (found) return true;
|
|
||||||
if (node instanceof AST_Scope && node !== fn) {
|
|
||||||
if (is_defun(node) && node.name.name == "await") found = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (node instanceof AST_Symbol && node.name == "await" && node !== fn.name) return found = true;
|
|
||||||
}));
|
|
||||||
if (found) return false;
|
|
||||||
}
|
|
||||||
var safe_to_inject = exp !== fn || fn.parent_scope.resolve() === scope;
|
var safe_to_inject = exp !== fn || fn.parent_scope.resolve() === scope;
|
||||||
if (scope instanceof AST_Toplevel) {
|
if (scope instanceof AST_Toplevel) {
|
||||||
if (compressor.toplevel.vars) {
|
if (compressor.toplevel.vars) {
|
||||||
|
|||||||
@@ -597,3 +597,25 @@ issue_4406: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
node_version: ">=8"
|
node_version: ">=8"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4417: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(async function() {
|
||||||
|
console.log(function() {
|
||||||
|
return await => 0;
|
||||||
|
}().prototype);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(async function() {
|
||||||
|
console.log(function() {
|
||||||
|
return await => 0;
|
||||||
|
}().prototype);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user