(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();
});
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;
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();
}
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);
});
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,