rename async -> deferred

This commit is contained in:
Dmitry Vasilev
2022-12-02 04:31:16 +08:00
parent cbb902b992
commit 9ebacd6f2a
8 changed files with 129 additions and 129 deletions

View File

@@ -24,23 +24,23 @@ export const calltree_node_loc = node => node.toplevel
? {module: node.module}
: node.fn.__location
export const get_async_calls = state => state.calltree.children[1].children
export const get_deferred_calls = state => state.calltree.children[1].children
export const root_calltree_node = state =>
// Returns calltree node for toplevel
// It is either toplevel for entrypoint module, or for module that throw
// error and prevent entrypoint module from executing.
// state.calltree.children[1] is async calls
// state.calltree.children[1] is deferred calls
state.calltree.children[0]
export const root_calltree_module = state =>
root_calltree_node(state).module
export const make_calltree = (root_calltree_node, async_calls) => ({
export const make_calltree = (root_calltree_node, deferred_calls) => ({
id: 'calltree',
children: [
root_calltree_node,
{id: 'async_calls', children: async_calls},
{id: 'deferred_calls', children: deferred_calls},
]
})
@@ -191,7 +191,7 @@ const jump_calltree_node = (_state, _current_calltree_node) => {
if(
current_calltree_node.toplevel
||
parent.id == 'async_calls'
parent.id == 'deferred_calls'
) {
show_body = true
} else if(is_native_fn(current_calltree_node)) {
@@ -338,7 +338,7 @@ const arrow_down = state => {
)
}
if(next_node?.id == 'async_calls') {
if(next_node?.id == 'deferred_calls') {
if(next_node.children == null) {
next_node = null
} else {
@@ -374,7 +374,7 @@ const arrow_up = state => {
}
let next_node
if(next_child == null) {
next_node = parent.id == 'async_calls'
next_node = parent.id == 'deferred_calls'
? last(root_calltree_node(state))
: parent
} else {
@@ -388,7 +388,7 @@ const arrow_left = state => {
const is_expanded = state.calltree_node_is_expanded[current.id]
if(!is_expandable(current) || !is_expanded) {
const [parent] = path_to_root(state.calltree, current)
if(parent.id == 'calltree' || parent.id == 'async_calls') {
if(parent.id == 'calltree' || parent.id == 'deferred_calls') {
return state
} else {
return jump_calltree_node(state, parent)
@@ -637,11 +637,11 @@ export const find_call = (state, index) => {
const {
calltree,
call,
is_found_async_call,
async_call_index
is_found_deferred_call,
deferred_call_index
} = state.calltree_actions.find_call(
loc,
get_async_calls(state)
get_deferred_calls(state)
)
if(call == null) {
return add_calltree_node_by_loc(
@@ -656,18 +656,18 @@ export const find_call = (state, index) => {
let next_calltree, active_calltree_node
if(is_found_async_call) {
const async_calls = get_async_calls(state)
const prev_call = async_calls[async_call_index]
if(is_found_deferred_call) {
const deferred_calls = get_deferred_calls(state)
const prev_call = deferred_calls[deferred_call_index]
const merged = merge_calltrees(prev_call, calltree)
const next_async_calls = async_calls.map((c, i) =>
i == async_call_index
const next_deferred_calls = deferred_calls.map((c, i) =>
i == deferred_call_index
? merged
: c
)
next_calltree = make_calltree(
root_calltree_node(state),
next_async_calls,
next_deferred_calls,
)
active_calltree_node = find_same_node(
merged,
@@ -677,7 +677,7 @@ export const find_call = (state, index) => {
} else {
next_calltree = make_calltree(
merge_calltrees(root_calltree_node(state), calltree),
get_async_calls(state),
get_deferred_calls(state),
)
active_calltree_node = find_same_node(
root_calltree_node({calltree: next_calltree}),

View File

@@ -10,7 +10,7 @@ import {find_export} from './find_definitions.js'
import {eval_modules} from './eval.js'
import {
root_calltree_node, root_calltree_module, make_calltree,
get_async_calls,
get_deferred_calls,
calltree_commands,
add_frame, calltree_node_loc, expand_path,
initial_calltree_node, default_expand_path, toggle_expanded, active_frame,
@@ -179,7 +179,7 @@ const do_external_imports_loaded = (
const result = eval_modules(
state.parse_result,
external_imports,
state.on_async_call,
state.on_deferred_call,
state.calltree_changed_token,
)
const next = apply_eval_result(state, result)
@@ -202,7 +202,7 @@ const do_external_imports_loaded = (
const result = eval_modules(
state.parse_result,
external_imports,
state.on_async_call,
state.on_deferred_call,
state.calltree_changed_token,
{index: node.index, module: state.current_module},
)
@@ -746,14 +746,14 @@ const move_cursor = (s, index) => {
return do_move_cursor(state, index)
}
const on_async_call = (state, call, calltree_changed_token) => {
const on_deferred_call = (state, call, calltree_changed_token) => {
if(state.calltree_changed_token != calltree_changed_token) {
return state
}
return {...state,
calltree: make_calltree(
root_calltree_node(state),
[...(get_async_calls(state) ?? []), call],
[...(get_deferred_calls(state) ?? []), call],
),
logs: {...state.logs, logs: state.logs.logs.concat(collect_logs(call))},
}
@@ -839,6 +839,6 @@ export const COMMANDS = {
move_cursor,
eval_selection,
external_imports_loaded,
on_async_call,
on_deferred_call,
calltree: calltree_commands,
}

View File

@@ -3,7 +3,7 @@ import {el, stringify, fn_link, scrollIntoViewIfNeeded} from './domutils.js'
import {FLAGS} from '../feature_flags.js'
import {stringify_for_header} from './value_explorer.js'
import {find_node} from '../ast_utils.js'
import {is_expandable, root_calltree_node, get_async_calls} from '../calltree.js'
import {is_expandable, root_calltree_node, get_deferred_calls} from '../calltree.js'
// TODO perf - quadratic difficulty
const join = arr => arr.reduce(
@@ -170,23 +170,23 @@ export class CallTree {
root_calltree_node(state),
)
const prev_async_calls = get_async_calls(prev_state)
const async_calls = get_async_calls(state)
const prev_deferred_calls = get_deferred_calls(prev_state)
const deferred_calls = get_deferred_calls(state)
if(prev_async_calls != null) {
// Expand already existing async calls
for(let i = 0; i < prev_async_calls.length; i++) {
if(prev_deferred_calls != null) {
// Expand already existing deferred calls
for(let i = 0; i < prev_deferred_calls.length; i++) {
this.do_render_expand_node(
prev_state.calltree_node_is_expanded,
state.calltree_node_is_expanded,
prev_async_calls[i],
async_calls[i],
prev_deferred_calls[i],
deferred_calls[i],
)
}
// Add new async calls
for(let i = prev_async_calls.length; i < async_calls.length; i++) {
this.async_calls_root.appendChild(
this.render_node(async_calls[i])
// Add new deferred calls
for(let i = prev_deferred_calls.length; i < deferred_calls.length; i++) {
this.deferred_calls_root.appendChild(
this.render_node(deferred_calls[i])
)
}
}
@@ -227,14 +227,14 @@ export class CallTree {
this.render_select_node(null, state)
}
render_async_calls(state) {
render_deferred_calls(state) {
this.state = state
this.container.appendChild(
el('div', 'callnode',
el('div', 'call_el',
el('i', '', 'async calls'),
this.async_calls_root = el('div', 'callnode',
get_async_calls(state).map(call => this.render_node(call))
el('i', '', 'deferred calls'),
this.deferred_calls_root = el('div', 'callnode',
get_deferred_calls(state).map(call => this.render_node(call))
)
)
)

6
src/effects.js vendored
View File

@@ -3,7 +3,7 @@ import {color_file} from './color.js'
import {
root_calltree_node,
calltree_node_loc,
get_async_calls
get_deferred_calls
} from './calltree.js'
import {FLAGS} from './feature_flags.js'
import {exec, FILES_ROOT} from './index.js'
@@ -196,8 +196,8 @@ export const render_common_side_effects = (prev, next, command, ui) => {
ui.logs.rerender_logs(next.logs)
} else {
if(get_async_calls(prev) == null && get_async_calls(next) != null) {
ui.calltree.render_async_calls(next)
if(get_deferred_calls(prev) == null && get_deferred_calls(next) != null) {
ui.calltree.render_deferred_calls(next)
}
if(

View File

@@ -260,7 +260,7 @@ const codegen = (node, cxt, parent) => {
export const eval_modules = (
parse_result,
external_imports,
on_async_call,
on_deferred_call,
calltree_changed_token,
location
) => {
@@ -281,7 +281,7 @@ export const eval_modules = (
let searched_location
let found_call
let is_recording_async_calls
let is_recording_deferred_calls
let is_toplevel_call = true
const set_record_call = () => {
@@ -291,14 +291,14 @@ export const eval_modules = (
}
const expand_calltree_node = (node) => {
is_recording_async_calls = false
is_recording_deferred_calls = false
children = null
try {
node.fn.apply(node.context, node.args)
} catch(e) {
// do nothing. Exception was caught and recorded inside 'trace'
}
is_recording_async_calls = true
is_recording_deferred_calls = true
if(node.fn.__location != null) {
// fn is hosted, it created call, this time with children
const result = children[0]
@@ -315,24 +315,24 @@ export const eval_modules = (
}
}
const find_call = (location, async_calls) => {
const find_call = (location, deferred_calls) => {
searched_location = location
let is_found_async_call = false
let is_found_deferred_call = false
let i
let {calltree} = run()
is_recording_async_calls = false
if(found_call == null && async_calls != null) {
for(i = 0; i < async_calls.length; i++) {
const c = async_calls[i]
is_recording_deferred_calls = false
if(found_call == null && deferred_calls != null) {
for(i = 0; i < deferred_calls.length; i++) {
const c = deferred_calls[i]
try {
c.fn.apply(c.context, c.args)
} catch(e) {
// do nothing. Exception was caught and recorded inside 'trace'
}
if(found_call != null) {
is_found_async_call = true
is_found_deferred_call = true
calltree = children[0]
children = null
break
@@ -340,14 +340,14 @@ export const eval_modules = (
}
}
is_recording_async_calls = true
is_recording_deferred_calls = true
searched_location = null
const call = found_call
found_call = null
return {
is_found_async_call,
async_call_index: i,
is_found_deferred_call,
deferred_call_index: i,
calltree,
call
}
@@ -428,13 +428,13 @@ export const eval_modules = (
is_toplevel_call = is_toplevel_call_copy
if(is_recording_async_calls && is_toplevel_call) {
if(is_recording_deferred_calls && is_toplevel_call) {
if(children.length != 1) {
throw new Error('illegal state')
}
const call = children[0]
children = null
on_async_call(call, calltree_changed_token)
on_deferred_call(call, calltree_changed_token)
}
}
}
@@ -512,7 +512,7 @@ export const eval_modules = (
const run = () => {
is_recording_async_calls = false
is_recording_deferred_calls = false
const __modules = {
/* external_imports passed as an argument to function generated with
@@ -548,7 +548,7 @@ export const eval_modules = (
})()
current_call.children = children
if(!current_call.ok) {
is_recording_async_calls = true
is_recording_deferred_calls = true
children = null
return { modules: __modules, calltree: current_call }
}
@@ -557,7 +557,7 @@ export const eval_modules = (
.join('')
+
`
is_recording_async_calls = true
is_recording_deferred_calls = true
children = null
return { modules: __modules, calltree: current_call }
}
@@ -571,7 +571,7 @@ export const eval_modules = (
const actions = make_function(
'external_imports',
'on_async_call',
'on_deferred_call',
'calltree_changed_token',
codestring
)(
@@ -580,9 +580,9 @@ export const eval_modules = (
? null
: map_object(external_imports, (name, {module}) => module),
/* on_async_call */
/* on_deferred_call */
(call, calltree_changed_token) => {
return on_async_call(
return on_deferred_call(
assign_code(parse_result.modules, call),
calltree_changed_token,
)
@@ -597,16 +597,16 @@ export const eval_modules = (
const expanded = actions.expand_calltree_node(node)
return assign_code(parse_result.modules, expanded)
},
find_call: (loc, async_calls) => {
find_call: (loc, deferred_calls) => {
const {
is_found_async_call,
async_call_index,
is_found_deferred_call,
deferred_call_index,
calltree,
call
} = actions.find_call(loc, async_calls)
} = actions.find_call(loc, deferred_calls)
return {
is_found_async_call,
async_call_index,
is_found_deferred_call,
deferred_call_index,
calltree: assign_code(parse_result.modules, calltree),
// TODO: `call` does not have `code` property here. Currently it is
// worked around by callers. Refactor

View File

@@ -148,7 +148,7 @@ export const init = (container, _COMMANDS) => {
state = COMMANDS.get_initial_state({
...initial_state,
on_async_call: (...args) => exec('on_async_call', ...args)
on_deferred_call: (...args) => exec('on_deferred_call', ...args)
})
// Expose state for debugging

View File

@@ -2,7 +2,7 @@ import {find_leaf, ancestry, find_node} from '../src/ast_utils.js'
import {parse, print_debug_node} from '../src/parse_js.js'
import {eval_tree, eval_frame, eval_modules} from '../src/eval.js'
import {COMMANDS} from '../src/cmd.js'
import {root_calltree_node, active_frame, pp_calltree, get_async_calls}
import {root_calltree_node, active_frame, pp_calltree, get_deferred_calls}
from '../src/calltree.js'
import {color_file} from '../src/color.js'
import {
@@ -14,7 +14,7 @@ import {
assert_code_error,
parse_modules,
test_initial_state,
test_async_calls_state,
test_deferred_calls_state,
print_debug_ct_node,
} from './utils.js'
@@ -2339,7 +2339,7 @@ const y = x()`
)
}),
test('async calls', () => {
test('deferred calls', () => {
const code = `
export const fn = () => {
fn2()
@@ -2350,22 +2350,22 @@ const y = x()`
}
`
const {state: i, on_async_call} = test_async_calls_state(code)
const {state: i, on_deferred_call} = test_deferred_calls_state(code)
// Make async call
// Make deferred call
i.modules[''].fn(10)
const state = on_async_call(i)
const state = on_deferred_call(i)
assert_equal(state.logs.logs.length, 1)
const call = get_async_calls(state)[0]
const call = get_deferred_calls(state)[0]
assert_equal(call.fn.name, 'fn')
assert_equal(call.code.index, code.indexOf('() => {'))
assert_equal(call.args, [10])
// Expand call
const {state: expanded} = COMMANDS.calltree.click(state, call.id)
assert_equal(get_async_calls(expanded)[0].children[0].fn.name, 'fn2')
assert_equal(get_deferred_calls(expanded)[0].children[0].fn.name, 'fn2')
// Navigate logs
const nav = COMMANDS.calltree.navigate_logs_position(expanded, 0)
@@ -2375,79 +2375,79 @@ const y = x()`
assert_equal(nav2.state.current_calltree_node.fn.name, 'fn2')
}),
test('async calls calltree nav', () => {
test('deferred calls calltree nav', () => {
const code = `
const normal_call = () => {
}
normal_call(0)
export const async_call = () => {
export const deferred_call = () => {
}
`
const {state: i, on_async_call} = test_async_calls_state(code)
const {state: i, on_deferred_call} = test_deferred_calls_state(code)
// When there are no async calls, and we press arrow down, nothing should
// When there are no deferred calls, and we press arrow down, nothing should
// happen
const no_async_down =
const no_deferred_down =
COMMANDS.calltree.arrow_down(
COMMANDS.calltree.arrow_down(i).state
)
assert_equal(no_async_down.current_calltree_node.fn.name, 'normal_call')
assert_equal(no_deferred_down.current_calltree_node.fn.name, 'normal_call')
const after_async_calls = [1, 2, 3].reduce(
const after_deferred_calls = [1, 2, 3].reduce(
(s, a) => {
// Make async calls
i.modules[''].async_call(a)
return on_async_call(s)
// Make deferred calls
i.modules[''].deferred_call(a)
return on_deferred_call(s)
},
i
)
assert_equal(
get_async_calls(after_async_calls).map(c => c.args[0]),
get_deferred_calls(after_deferred_calls).map(c => c.args[0]),
[1,2,3]
)
assert_equal(after_async_calls.current_calltree_node.toplevel, true)
assert_equal(after_deferred_calls.current_calltree_node.toplevel, true)
const down = COMMANDS.calltree.arrow_down(after_async_calls).state
const down = COMMANDS.calltree.arrow_down(after_deferred_calls).state
const first_async_call_selected = COMMANDS.calltree.arrow_down(
COMMANDS.calltree.arrow_down(after_async_calls).state
const first_deferred_call_selected = COMMANDS.calltree.arrow_down(
COMMANDS.calltree.arrow_down(after_deferred_calls).state
).state
// After we press arrow down, first async call gets selected
// After we press arrow down, first deferred call gets selected
assert_equal(
first_async_call_selected.current_calltree_node.args[0],
first_deferred_call_selected.current_calltree_node.args[0],
1,
)
// One more arrow down, second async call gets selected
// One more arrow down, second deferred call gets selected
assert_equal(
COMMANDS.calltree.arrow_down(first_async_call_selected)
COMMANDS.calltree.arrow_down(first_deferred_call_selected)
.state
.current_calltree_node
.args[0],
2
)
// After we press arrow up when first async call selected, we select last
// visible non async call
// After we press arrow up when first deferred call selected, we select last
// visible non deferred call
assert_equal(
COMMANDS.calltree.arrow_up(first_async_call_selected)
COMMANDS.calltree.arrow_up(first_deferred_call_selected)
.state
.current_calltree_node
.args[0],
0
)
// After we press arrow left when first async call selected, we stay on
// After we press arrow left when first deferred call selected, we stay on
// this call
assert_equal(
COMMANDS.calltree.arrow_left(first_async_call_selected)
COMMANDS.calltree.arrow_left(first_deferred_call_selected)
.current_calltree_node
.args[0],
1
@@ -2456,7 +2456,7 @@ const y = x()`
}),
test('async_calls find_call', () => {
test('deferred_calls find_call', () => {
const code = `
export const fn = () => {
fn2()
@@ -2467,12 +2467,12 @@ const y = x()`
}
`
const {state: i, on_async_call} = test_async_calls_state(code)
const {state: i, on_deferred_call} = test_deferred_calls_state(code)
// Make async call
// Make deferred call
i.modules[''].fn()
const state = on_async_call(i)
const state = on_deferred_call(i)
const {state: moved} = COMMANDS.move_cursor(state, code.indexOf('fn2'))
assert_equal(moved.active_calltree_node.fn.name, 'fn')
@@ -2486,45 +2486,45 @@ const y = x()`
assert_equal(move_back.active_calltree_node.fn.name, 'fn')
}),
test('async_calls find_call then async_call bug', () => {
test('deferred_calls find_call then deferred_call bug', () => {
const code = `
export const fn = () => { /* label */ }
`
const {state: i, on_async_call} = test_async_calls_state(code)
const {state: i, on_deferred_call} = test_deferred_calls_state(code)
// Make async call
// Make deferred call
i.modules[''].fn(1)
const state = on_async_call(i)
const state = on_deferred_call(i)
// find call
const {state: moved} = COMMANDS.move_cursor(state, code.indexOf('label'))
// Make async call
// Make deferred call
i.modules[''].fn(2)
const result = on_async_call(moved)
const result = on_deferred_call(moved)
// there was a bug throwing error when added second async call
assert_equal(get_async_calls(result).map(c => c.args), [[1], [2]])
// there was a bug throwing error when added second deferred call
assert_equal(get_deferred_calls(result).map(c => c.args), [[1], [2]])
}),
test('async_calls discard on code rerun', () => {
test('deferred_calls discard on code rerun', () => {
const code = `
export const fn = () => { /* label */ }
`
const {state: i, on_async_call} = test_async_calls_state(code)
const {state: i, on_deferred_call} = test_deferred_calls_state(code)
const input = COMMANDS.input(i, code, 0).state
// Make async call, calling fn from previous code
// Make deferred call, calling fn from previous code
i.modules[''].fn(1)
const result = on_async_call(input)
const result = on_deferred_call(input)
// Async calls must be null, because async calls from previous executions
// deferred calls must be null, because deferred calls from previous executions
// must be discarded
assert_equal(get_async_calls(result), null)
assert_equal(get_deferred_calls(result), null)
}),
]

View File

@@ -40,26 +40,26 @@ export const test_initial_state = (code, state) => {
)
}
export const test_async_calls_state = code => {
const {get_async_call, on_async_call} = (new Function(`
export const test_deferred_calls_state = code => {
const {get_deferred_call, on_deferred_call} = (new Function(`
let call, calltree_changed_token
return {
get_async_call() {
get_deferred_call() {
return [call, calltree_changed_token]
},
on_async_call(_call, _calltree_changed_token) {
on_deferred_call(_call, _calltree_changed_token) {
call = _call
calltree_changed_token = _calltree_changed_token
}
}
`))()
const state = test_initial_state(code, { on_async_call })
const state = test_initial_state(code, { on_deferred_call })
return {
state,
get_async_call,
on_async_call: state => COMMANDS.on_async_call(state, ...get_async_call())
get_deferred_call,
on_deferred_call: state => COMMANDS.on_deferred_call(state, ...get_deferred_call())
}
}