diff --git a/src/calltree.js b/src/calltree.js index 74f3fb6..159597c 100644 --- a/src/calltree.js +++ b/src/calltree.js @@ -630,7 +630,10 @@ export const find_call = (state, index) => { } const loc = {index: node.index, module: state.current_module} - const {calltree, call} = state.calltree_actions.find_call(loc) + const {calltree, call} = state.calltree_actions.find_call( + loc, + get_async_calls(state) + ) if(call == null) { return add_calltree_node_by_loc( // Remove active_calltree_node diff --git a/src/eval.js b/src/eval.js index 8c9db91..e918a58 100644 --- a/src/eval.js +++ b/src/eval.js @@ -310,9 +310,17 @@ export const eval_modules = ( } } - const find_call = (location) => { + const find_call = (location, async_calls) => { searched_location = location const {modules, calltree} = run() + if(found_call == null && async_calls != null) { + for(let c of async_calls) { + c.fn.apply(c.context, c.args) + if(found_call != null) { + break + } + } + } searched_location = null const call = found_call found_call = null @@ -554,8 +562,8 @@ export const eval_modules = ( const expanded = actions.expand_calltree_node(node) return assign_code(parse_result.modules, expanded) }, - find_call: (loc) => { - const {modules, calltree, call} = actions.find_call(loc) + find_call: (loc, async_calls) => { + const {modules, calltree, call} = actions.find_call(loc, async_calls) return { calltree: assign_code(parse_result.modules, calltree), // TODO: `call` does not have `code` property here. Currently it is diff --git a/test/test.js b/test/test.js index acbe896..5d05b72 100644 --- a/test/test.js +++ b/test/test.js @@ -2360,4 +2360,91 @@ const y = x()` assert_equal(nav2.state.current_calltree_node.fn.name, 'fn2') }), + // TODO + /* + test('async calls calltree nav', () => { + const code = ` + const fn = () => { + fn2() + } + + const fn2 = () => { + console.log(1) + } + + // Use Function constructor to exec impure code for testing + new Function('fn', 'globalThis.__run_async_call = fn')(fn) + ` + + const {get_async_call, on_async_call} = (new Function(` + let call + return { + get_async_call() { + return call + }, + on_async_call(_call) { + call = _call + } + } + `))() + + const i = test_initial_state(code, { on_async_call }) + globalThis.__run_async_call(10) + const call = get_async_call() + assert_equal(call.fn.name, 'fn') + assert_equal(call.code.index, code.indexOf('() => {')) + assert_equal(call.args, [10]) + const state = COMMANDS.on_async_call(i, call) + assert_equal(get_async_calls(state), [call]) + + assert_equal(state.logs.logs.length, 1) + + // Expand call + const {state: expanded} = COMMANDS.calltree.click(state, call.id) + assert_equal(get_async_calls(expanded)[0].children[0].fn.name, 'fn2') + + // Navigate logs + const nav = COMMANDS.calltree.navigate_logs_position(expanded, 0) + assert_equal(nav.state.current_calltree_node.is_log, true) + + const nav2 = COMMANDS.calltree.arrow_left(nav.state) + assert_equal(nav2.state.current_calltree_node.fn.name, 'fn2') + }), + */ + + test_only('async_calls find_call', () => { + const code = ` + const fn = () => { + fn2() + } + + const fn2 = () => { + console.log(1) + } + + // Use Function constructor to exec impure code for testing + new Function('fn', 'globalThis.__run_async_call = fn')(fn) + ` + + const {get_async_call, on_async_call} = (new Function(` + let call + return { + get_async_call() { + return call + }, + on_async_call(_call) { + call = _call + } + } + `))() + + const i = test_initial_state(code, { on_async_call }) + globalThis.__run_async_call(10) + const call = get_async_call() + const state = COMMANDS.on_async_call(i, call) + + const {state: moved} = COMMANDS.move_cursor(state, code.indexOf('fn2')) + console.log('active_calltree_node', moved.active_calltree_node) + }), + ]