diff --git a/src/eval.js b/src/eval.js index d558da1..7766884 100644 --- a/src/eval.js +++ b/src/eval.js @@ -211,7 +211,7 @@ const codegen = (node, cxt, parent) => { + ']' } else if(node.type == 'unary') { if(node.operator == 'await') { - return `(await __with_restore_children(${do_codegen(node.expr)}))` + return `(await __do_await(${do_codegen(node.expr)}))` } else { return '(' + node.operator + ' ' + do_codegen(node.expr) + ')' } @@ -367,9 +367,15 @@ export const eval_modules = ( } const set_promise_status = value => { + // TODO refactor, put is_status_requested inside status if(value instanceof Promise) { + if(value.is_status_requested) { + return value + } + value.is_status_requested = true // record stack for async calls, so expand calls works sync set_record_call() + // TODO why we set status for wrapped value and not for wrapper? return value .then(v => { value.status = {ok: true, value: v} @@ -384,7 +390,7 @@ export const eval_modules = ( } } - const __with_restore_children = async value => { + const __do_await = async value => { // children is an array of child calls for current function call. But it // can be null to save one empty array allocation in case it has no child // calls. Allocate array now, so we can have a reference to this array @@ -393,6 +399,17 @@ export const eval_modules = ( children = [] } const children_copy = children + if(value instanceof Promise && !value.is_status_requested) { + value.is_status_requested = true + value.then( + v => { + value.status = {ok: true, value: v} + }, + e => { + value.status = {ok: false, error: e} + } + ) + } try { return await value } finally { diff --git a/test/test.js b/test/test.js index 14eb14b..596e816 100644 --- a/test/test.js +++ b/test/test.js @@ -2821,6 +2821,19 @@ const y = x()` assert_equal(root.children.at(-1).children[0].fn.name, 'x') }), + test('async/await await promise wrapped to some data structure', async () => { + const i = await assert_code_evals_to_async( + ` + const async_fn = async () => 1 + const x = () => { + return {promise: async_fn()} + } + await x().promise + `, + 1 + ) + }), + /* // TODO test('async/await move_cursor', async () => {