enhance inline (#5243)
This commit is contained in:
@@ -12778,14 +12778,19 @@ Compressor.prototype.compress = function(node) {
|
||||
|
||||
(function(def) {
|
||||
def(AST_Node, noop);
|
||||
def(AST_Await, function(compressor, scope) {
|
||||
return this.expression.try_inline(compressor, scope);
|
||||
});
|
||||
def(AST_Call, function(compressor, scope) {
|
||||
if (compressor.option("inline") < 4) return;
|
||||
var call = this;
|
||||
if (call.is_expr_pure(compressor)) return;
|
||||
var fn = call.expression;
|
||||
if (!(fn instanceof AST_Function)) return;
|
||||
if (!(fn instanceof AST_LambdaExpression)) return;
|
||||
if (fn.name) return;
|
||||
if (fn.uses_arguments) return;
|
||||
if (is_arrow(fn) && fn.value) return;
|
||||
if (is_generator(fn)) return;
|
||||
if (fn.contains_this()) return;
|
||||
if (!scope) scope = find_scope(compressor);
|
||||
var defined = new Dictionary();
|
||||
@@ -12795,6 +12800,7 @@ Compressor.prototype.compress = function(node) {
|
||||
});
|
||||
scope = scope.parent_scope;
|
||||
}
|
||||
if (is_async(fn) && !(compressor.option("awaits") && is_async(scope))) return;
|
||||
var names = scope.var_names();
|
||||
if (!fn.variables.all(function(def, name) {
|
||||
if (!defined.has(name) && !names.has(name)) return true;
|
||||
@@ -12864,9 +12870,16 @@ Compressor.prototype.compress = function(node) {
|
||||
syms.each(function(orig, id) {
|
||||
[].unshift.apply(defs[id].orig, orig);
|
||||
});
|
||||
return make_node(AST_BlockStatement, call, {
|
||||
var inlined = make_node(AST_BlockStatement, call, {
|
||||
body: body.concat(fn.body, make_node(AST_Return, call, { value: null })),
|
||||
});
|
||||
if (is_async(fn)) scan_local_returns(inlined, function(node) {
|
||||
var value = node.value;
|
||||
if (!value) return;
|
||||
if (is_undefined(value)) return;
|
||||
node.value = make_node(AST_Await, call, { expression: value });
|
||||
});
|
||||
return inlined;
|
||||
|
||||
function process(sym, argname) {
|
||||
var def = argname.definition();
|
||||
@@ -12901,11 +12914,31 @@ Compressor.prototype.compress = function(node) {
|
||||
}
|
||||
node.value = make_node(AST_UnaryPrefix, self, {
|
||||
operator: op,
|
||||
expression: value || make_node(AST_Undefined, node),
|
||||
}).optimize(compressor);
|
||||
expression: value || make_node(AST_Undefined, node).transform(compressor),
|
||||
});
|
||||
});
|
||||
return inlined;
|
||||
})
|
||||
});
|
||||
def(AST_Yield, function(compressor, scope) {
|
||||
if (!compressor.option("yields")) return;
|
||||
if (!this.nested) return;
|
||||
var call = this.expression;
|
||||
if (call.TYPE != "Call") return;
|
||||
var fn = call.expression;
|
||||
switch (fn.CTOR) {
|
||||
case AST_AsyncGeneratorFunction:
|
||||
fn = make_node(AST_AsyncFunction, fn, fn);
|
||||
break;
|
||||
case AST_GeneratorFunction:
|
||||
fn = make_node(AST_Function, fn, fn);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
call = call.clone();
|
||||
call.expression = fn;
|
||||
return call.try_inline(compressor, scope);
|
||||
});
|
||||
})(function(node, func) {
|
||||
node.DEFMETHOD("try_inline", func);
|
||||
});
|
||||
|
||||
@@ -395,6 +395,253 @@ inline_await_this: {
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
inline_block: {
|
||||
options = {
|
||||
awaits: true,
|
||||
if_return: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
console.log("foo");
|
||||
(async function() {
|
||||
console.log("bar");
|
||||
(async function() {
|
||||
for (var a of [ "baz" ])
|
||||
return a;
|
||||
})();
|
||||
})().then(console.log);
|
||||
console.log("moo");
|
||||
}
|
||||
expect: {
|
||||
console.log("foo");
|
||||
(async function() {
|
||||
console.log("bar");
|
||||
for (var a of [ "baz" ])
|
||||
return void await a;
|
||||
})().then(console.log);
|
||||
console.log("moo");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"moo",
|
||||
"undefined",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
inline_block_async: {
|
||||
options = {
|
||||
awaits: true,
|
||||
if_return: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
console.log("foo");
|
||||
(async function() {
|
||||
console.log("bar");
|
||||
(async function() {
|
||||
for (var a of [ "baz" ])
|
||||
return {
|
||||
then(r) {
|
||||
console.log("moo");
|
||||
r(a);
|
||||
},
|
||||
};
|
||||
})();
|
||||
})().then(console.log);
|
||||
console.log("moz");
|
||||
}
|
||||
expect: {
|
||||
console.log("foo");
|
||||
(async function() {
|
||||
console.log("bar");
|
||||
for (var a of [ "baz" ])
|
||||
return void await {
|
||||
then(r) {
|
||||
console.log("moo");
|
||||
r(a);
|
||||
},
|
||||
};
|
||||
})().then(console.log);
|
||||
console.log("moz");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"moz",
|
||||
"moo",
|
||||
"undefined",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
inline_block_await: {
|
||||
options = {
|
||||
awaits: true,
|
||||
if_return: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
console.log("foo");
|
||||
(async function() {
|
||||
console.log("bar");
|
||||
await async function() {
|
||||
for (var a of [ "baz" ])
|
||||
return a;
|
||||
}();
|
||||
})().then(console.log);
|
||||
console.log("moo");
|
||||
}
|
||||
expect: {
|
||||
console.log("foo");
|
||||
(async function() {
|
||||
console.log("bar");
|
||||
for (var a of [ "baz" ])
|
||||
return void await a;
|
||||
})().then(console.log);
|
||||
console.log("moo");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"moo",
|
||||
"undefined",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
inline_block_await_async: {
|
||||
options = {
|
||||
awaits: true,
|
||||
if_return: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
console.log("foo");
|
||||
(async function() {
|
||||
console.log("bar");
|
||||
await async function() {
|
||||
for (var a of [ "baz" ])
|
||||
return {
|
||||
then(r) {
|
||||
console.log("moo");
|
||||
r(a);
|
||||
},
|
||||
};
|
||||
}();
|
||||
})().then(console.log);
|
||||
console.log("moz");
|
||||
}
|
||||
expect: {
|
||||
console.log("foo");
|
||||
(async function() {
|
||||
console.log("bar");
|
||||
for (var a of [ "baz" ])
|
||||
return void await {
|
||||
then(r) {
|
||||
console.log("moo");
|
||||
r(a);
|
||||
},
|
||||
};;
|
||||
})().then(console.log);
|
||||
console.log("moz");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"moz",
|
||||
"moo",
|
||||
"undefined",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
inline_block_return: {
|
||||
options = {
|
||||
awaits: true,
|
||||
if_return: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
console.log("foo");
|
||||
(async function() {
|
||||
console.log("bar");
|
||||
return async function() {
|
||||
for (var a of [ "baz" ])
|
||||
return a;
|
||||
}();
|
||||
})().then(console.log);
|
||||
console.log("moo");
|
||||
}
|
||||
expect: {
|
||||
console.log("foo");
|
||||
(async function() {
|
||||
console.log("bar");
|
||||
for (var a of [ "baz" ])
|
||||
return a;
|
||||
})().then(console.log);
|
||||
console.log("moo");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"moo",
|
||||
"baz",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
inline_block_return_async: {
|
||||
options = {
|
||||
awaits: true,
|
||||
if_return: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
console.log("foo");
|
||||
(async function() {
|
||||
console.log("bar");
|
||||
return async function() {
|
||||
for (var a of [ "baz" ])
|
||||
return {
|
||||
then(r) {
|
||||
console.log("moo");
|
||||
r(a);
|
||||
},
|
||||
};
|
||||
}();
|
||||
})().then(console.log);
|
||||
console.log("moz");
|
||||
}
|
||||
expect: {
|
||||
console.log("foo");
|
||||
(async function() {
|
||||
console.log("bar");
|
||||
for (var a of [ "baz" ])
|
||||
return {
|
||||
then(r) {
|
||||
console.log("moo");
|
||||
r(a);
|
||||
},
|
||||
};
|
||||
})().then(console.log);
|
||||
console.log("moz");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"moz",
|
||||
"moo",
|
||||
"baz",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
await_unary: {
|
||||
options = {
|
||||
awaits: true,
|
||||
|
||||
@@ -749,7 +749,7 @@ lift_sequence: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
inline_nested_yield: {
|
||||
inline_nested: {
|
||||
options = {
|
||||
inline: true,
|
||||
sequences: true,
|
||||
@@ -784,6 +784,94 @@ inline_nested_yield: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
inline_nested_async: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
yields: true,
|
||||
}
|
||||
input: {
|
||||
console.log("foo");
|
||||
var a = async function*() {
|
||||
console.log(await(yield* async function*() {
|
||||
yield {
|
||||
then: r => r("bar"),
|
||||
};
|
||||
return "baz";
|
||||
}()));
|
||||
}();
|
||||
console.log("moo");
|
||||
a.next().then(function f(b) {
|
||||
console.log(b.value);
|
||||
b.done || a.next().then(f);
|
||||
});
|
||||
console.log("moz");
|
||||
}
|
||||
expect: {
|
||||
console.log("foo");
|
||||
var a = async function*() {
|
||||
console.log((yield {
|
||||
then: r => r("bar"),
|
||||
}, await "baz"));
|
||||
}();
|
||||
console.log("moo"),
|
||||
a.next().then(function f(b) {
|
||||
console.log(b.value),
|
||||
b.done || a.next().then(f);
|
||||
}),
|
||||
console.log("moz");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"moo",
|
||||
"moz",
|
||||
"bar",
|
||||
"baz",
|
||||
"undefined",
|
||||
]
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
inline_nested_block: {
|
||||
options = {
|
||||
if_return: true,
|
||||
inline: true,
|
||||
yields: true,
|
||||
}
|
||||
input: {
|
||||
var a = function*() {
|
||||
yield* function*() {
|
||||
for (var a of [ "foo", "bar" ])
|
||||
yield a;
|
||||
return "FAIL";
|
||||
}();
|
||||
}(), b;
|
||||
do {
|
||||
b = a.next();
|
||||
console.log(b.value);
|
||||
} while (!b.done);
|
||||
}
|
||||
expect: {
|
||||
var a = function*() {
|
||||
for (var a of [ "foo", "bar" ])
|
||||
yield a;
|
||||
"FAIL";
|
||||
}(), b;
|
||||
do {
|
||||
b = a.next();
|
||||
console.log(b.value);
|
||||
} while (!b.done);
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"undefined",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
dont_inline_nested: {
|
||||
options = {
|
||||
inline: true,
|
||||
|
||||
Reference in New Issue
Block a user