This commit is contained in:
Dmitry Vasilev
2022-12-07 05:42:33 +08:00
parent 707c34bc66
commit 3ea0bedc31
7 changed files with 84 additions and 36 deletions

View File

@@ -7,6 +7,7 @@ import {eval_frame} from './eval.js'
export const pp_calltree = tree => ({ export const pp_calltree = tree => ({
id: tree.id, id: tree.id,
ok: tree.ok, ok: tree.ok,
value: tree.value,
is_log: tree.is_log, is_log: tree.is_log,
has_more_children: tree.has_more_children, has_more_children: tree.has_more_children,
string: tree.code?.string, string: tree.code?.string,

14
src/effects.js vendored
View File

@@ -177,7 +177,11 @@ export const render_common_side_effects = async (prev, next, command, ui) => {
load_external_imports(next) load_external_imports(next)
} }
if(prev.eval_modules_state != next.eval_modules_state) { if(
prev.eval_modules_state != next.eval_modules_state
&&
next.eval_modules_state != null
) {
const s = next.eval_modules_state const s = next.eval_modules_state
s.promise.then(result => { s.promise.then(result => {
exec('eval_modules_finished', result, s.node, s.toplevel) exec('eval_modules_finished', result, s.node, s.toplevel)
@@ -188,7 +192,13 @@ export const render_common_side_effects = async (prev, next, command, ui) => {
render_parse_result(ui, next) render_parse_result(ui, next)
} }
if(!next.parse_result.ok || next.loading_external_imports_state != null) { if(
!next.parse_result.ok
||
next.loading_external_imports_state != null
||
next.eval_modules_state != null
) {
// TODO if loading external imports, show loading indicator // TODO if loading external imports, show loading indicator
ui.calltree.clear_calltree() ui.calltree.clear_calltree()

View File

@@ -260,16 +260,6 @@ const codegen = (node, cxt, parent) => {
} }
} }
/* TODO remove
const sync_promise = value => {
if(value instanceof run_window.Promise.Original) {
return value
} else {
return {is_sync_promise: true, then: fn => sync_promise(fn(value))}
}
}
*/
export const eval_modules = ( export const eval_modules = (
parse_result, parse_result,
external_imports, external_imports,
@@ -955,6 +945,7 @@ const do_eval_frame_expr = (node, scope, callsleft) => {
ok = true ok = true
value = typeof(expr.result.value) value = typeof(expr.result.value)
} else if(node.operator == '-') { } else if(node.operator == '-') {
ok = true
value = - expr.result.value value = - expr.result.value
} else if(node.operator == 'await') { } else if(node.operator == 'await') {
const run_window = globalThis.run_window ?? globalThis const run_window = globalThis.run_window ?? globalThis

View File

@@ -203,9 +203,20 @@ export const topsort_modules = (modules) => {
} }
export const has_toplevel_await = modules => export const has_toplevel_await = modules =>
Object.values(modules).some(m => Object.values(modules).some(m => node_has_toplevel_await(m))
m.children.find(c => c.type == 'unary' && c.operator == 'await' ) != null
) const node_has_toplevel_await = node => {
if(node.type == 'unary' && node.operator == 'await') {
return true
}
if(node.type == 'function_expr') {
return false
}
if(node.children == null) {
return false
}
return node.children.find(c => node_has_toplevel_await(c)) != null
}
// TODO not implemented // TODO not implemented
// TODO detect cycles when loading modules // TODO detect cycles when loading modules

View File

@@ -13,11 +13,23 @@ export const patch_promise = window => {
(resolve, reject) => { (resolve, reject) => {
fn( fn(
(value) => { (value) => {
if(value instanceof window.Promise.Original) {
value
.then(v => {
this.status = {ok: true, value: v}
resolve(v)
})
.catch(e => {
this.status = {ok: false, error: e}
reject(e)
})
} else {
status = {ok: true, value} status = {ok: true, value}
if(is_constructor_finished) { if(is_constructor_finished) {
this.status = status this.status = status
} }
resolve(value) resolve(value)
}
}, },
(error) => { (error) => {
status = {ok: false, error} status = {ok: false, error}

View File

@@ -2600,7 +2600,7 @@ const y = x()`
) )
}), }),
test('async/await await Promise', async () => { test('async/await await resolved Promise', async () => {
await assert_code_evals_to_async( await assert_code_evals_to_async(
` `
await Promise.resolve(123) await Promise.resolve(123)
@@ -2609,6 +2609,34 @@ const y = x()`
) )
}), }),
test('async/await await Promise resolved with resolved Promise', async () => {
await assert_code_evals_to_async(
`
await Promise.resolve(Promise.resolve(123))
`,
123
)
}),
test('async/await await Promise resolved with async', async () => {
await assert_code_evals_to_async(
`
const x = async () => 1
await Promise.resolve(x())
`,
1
)
}),
test('async/await await Promise resolved with rejected Promise', async () => {
await assert_code_error_async(
`
await Promise.resolve(Promise.reject('boom'))
`,
'boom',
)
}),
test('async/await await Promise returned from async function', async () => { test('async/await await Promise returned from async function', async () => {
await assert_code_evals_to_async( await assert_code_evals_to_async(
` `
@@ -2640,15 +2668,6 @@ const y = x()`
) )
}), }),
test('async/await await rejected Promise', async () => {
await assert_code_error_async(
`
await Promise.reject('boom')
`,
'boom'
)
}),
test('async/await await rejected Promise returned from async', async () => { test('async/await await rejected Promise returned from async', async () => {
await assert_code_error_async( await assert_code_error_async(
` `
@@ -2659,10 +2678,14 @@ const y = x()`
) )
}), }),
// TODO test('async/await Promise.all', async () => {
//assert_equal('s', active_frame await assert_code_evals_to_async(
//const result = await s.eval_modules_state `
//const move = COMMANDS.move_cursor(s, code.indexOf('await x()')).state const x = async i => i
//log('m', root_calltree_node(move).children[0].children[0].value) await Promise.all([x(0), x(1), x(2)])
//log(s.parse_result.modules['']) `,
[0,1,2]
)
}),
] ]

View File

@@ -1,6 +1,6 @@
import {parse, print_debug_node, load_modules} from '../src/parse_js.js' import {parse, print_debug_node, load_modules} from '../src/parse_js.js'
import {eval_tree, eval_frame} from '../src/eval.js' import {eval_tree, eval_frame} from '../src/eval.js'
import {active_frame} from '../src/calltree.js' import {active_frame, pp_calltree} from '../src/calltree.js'
import {COMMANDS} from '../src/cmd.js' import {COMMANDS} from '../src/cmd.js'
Object.assign(globalThis, {log: console.log}) Object.assign(globalThis, {log: console.log})