discard async calls from prev code run

This commit is contained in:
Dmitry Vasilev
2022-11-29 04:22:56 +08:00
parent 0332d5a0b8
commit 6ea107d057
4 changed files with 72 additions and 66 deletions

View File

@@ -180,6 +180,7 @@ const do_external_imports_loaded = (
state.parse_result, state.parse_result,
external_imports, external_imports,
state.on_async_call, state.on_async_call,
state.calltree_changed_token,
) )
const next = apply_eval_result(state, result) const next = apply_eval_result(state, result)
@@ -202,6 +203,7 @@ const do_external_imports_loaded = (
state.parse_result, state.parse_result,
external_imports, external_imports,
state.on_async_call, state.on_async_call,
state.calltree_changed_token,
{index: node.index, module: state.current_module}, {index: node.index, module: state.current_module},
) )
@@ -744,7 +746,10 @@ const move_cursor = (s, index) => {
return do_move_cursor(state, index) return do_move_cursor(state, index)
} }
const on_async_call = (state, call) => { const on_async_call = (state, call, calltree_changed_token) => {
if(state.calltree_changed_token != calltree_changed_token) {
return state
}
return {...state, return {...state,
calltree: make_calltree( calltree: make_calltree(
root_calltree_node(state), root_calltree_node(state),

View File

@@ -257,6 +257,7 @@ export const eval_modules = (
parse_result, parse_result,
external_imports, external_imports,
on_async_call, on_async_call,
calltree_changed_token,
location location
) => { ) => {
// TODO gensym __modules, __exports // TODO gensym __modules, __exports
@@ -429,7 +430,7 @@ export const eval_modules = (
} }
const call = children[0] const call = children[0]
children = null children = null
on_async_call(call) on_async_call(call, calltree_changed_token)
} }
} }
} }
@@ -567,6 +568,7 @@ export const eval_modules = (
const actions = make_function( const actions = make_function(
'external_imports', 'external_imports',
'on_async_call', 'on_async_call',
'calltree_changed_token',
codestring codestring
)( )(
/* external_imports */ /* external_imports */
@@ -575,7 +577,15 @@ export const eval_modules = (
: map_object(external_imports, (name, {module}) => module), : map_object(external_imports, (name, {module}) => module),
/* on_async_call */ /* on_async_call */
call => on_async_call(assign_code(parse_result.modules, call)) (call, calltree_changed_token) => {
return on_async_call(
assign_code(parse_result.modules, call),
calltree_changed_token,
)
},
/* calltree_changed_token */
calltree_changed_token
) )
const calltree_actions = { const calltree_actions = {

View File

@@ -14,6 +14,7 @@ import {
assert_code_error, assert_code_error,
parse_modules, parse_modules,
test_initial_state, test_initial_state,
test_async_calls_state,
print_debug_ct_node, print_debug_ct_node,
} from './utils.js' } from './utils.js'
@@ -2324,31 +2325,18 @@ const y = x()`
} }
` `
const {get_async_call, on_async_call} = (new Function(` const {state: i, on_async_call} = test_async_calls_state(code)
let call
return {
get_async_call() {
return call
},
on_async_call(_call) {
call = _call
}
}
`))()
const i = test_initial_state(code, { on_async_call })
// Make async call // Make async call
i.modules[''].fn(10) i.modules[''].fn(10)
const call = get_async_call() const state = on_async_call(i)
assert_equal(state.logs.logs.length, 1)
const call = get_async_calls(state)[0]
assert_equal(call.fn.name, 'fn') assert_equal(call.fn.name, 'fn')
assert_equal(call.code.index, code.indexOf('() => {')) assert_equal(call.code.index, code.indexOf('() => {'))
assert_equal(call.args, [10]) 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 // Expand call
const {state: expanded} = COMMANDS.calltree.click(state, call.id) const {state: expanded} = COMMANDS.calltree.click(state, call.id)
@@ -2373,26 +2361,13 @@ const y = x()`
} }
` `
const {get_async_call, on_async_call} = (new Function(` const {state: i, on_async_call} = test_async_calls_state(code)
let call
return {
get_async_call() {
return call
},
on_async_call(_call) {
call = _call
}
}
`))()
const i = test_initial_state(code, { on_async_call })
const after_async_calls = [1, 2, 3].reduce( const after_async_calls = [1, 2, 3].reduce(
(s, a) => { (s, a) => {
// Make async calls // Make async calls
i.modules[''].async_call(a) i.modules[''].async_call(a)
const call = get_async_call() return on_async_call(s)
return COMMANDS.on_async_call(s, call)
}, },
i i
) )
@@ -2458,25 +2433,12 @@ const y = x()`
} }
` `
const {get_async_call, on_async_call} = (new Function(` const {state: i, on_async_call} = test_async_calls_state(code)
let call
return {
get_async_call() {
return call
},
on_async_call(_call) {
call = _call
}
}
`))()
const i = test_initial_state(code, { on_async_call })
// Make async call // Make async call
i.modules[''].fn() i.modules[''].fn()
const call = get_async_call() const state = on_async_call(i)
const state = COMMANDS.on_async_call(i, call)
const {state: moved} = COMMANDS.move_cursor(state, code.indexOf('fn2')) const {state: moved} = COMMANDS.move_cursor(state, code.indexOf('fn2'))
assert_equal(moved.active_calltree_node.fn.name, 'fn') assert_equal(moved.active_calltree_node.fn.name, 'fn')
@@ -2495,24 +2457,12 @@ const y = x()`
export const fn = () => { /* label */ } export const fn = () => { /* label */ }
` `
const {get_async_call, on_async_call} = (new Function(` const {state: i, on_async_call} = test_async_calls_state(code)
let call
return {
get_async_call() {
return call
},
on_async_call(_call) {
call = _call
}
}
`))()
const i = test_initial_state(code, { on_async_call })
// Make async call // Make async call
i.modules[''].fn(1) i.modules[''].fn(1)
const state = COMMANDS.on_async_call(i, get_async_call()) const state = on_async_call(i)
// find call // find call
const {state: moved} = COMMANDS.move_cursor(state, code.indexOf('label')) const {state: moved} = COMMANDS.move_cursor(state, code.indexOf('label'))
@@ -2520,9 +2470,27 @@ const y = x()`
// Make async call // Make async call
i.modules[''].fn(2) i.modules[''].fn(2)
const result = COMMANDS.on_async_call(moved, get_async_call()) const result = on_async_call(moved)
// there was a bug throwing error when added second async call // there was a bug throwing error when added second async call
assert_equal(get_async_calls(result).map(c => c.args), [[1], [2]]) assert_equal(get_async_calls(result).map(c => c.args), [[1], [2]])
}), }),
test('async_calls discard on code rerun', () => {
const code = `
export const fn = () => { /* label */ }
`
const {state: i, on_async_call} = test_async_calls_state(code)
const input = COMMANDS.input(i, code, 0).state
// Make async call, calling fn from previous code
i.modules[''].fn(1)
const result = on_async_call(input)
// Async calls must be null, because async calls from previous executions
// must be discarded
assert_equal(get_async_calls(result), null)
}),
] ]

View File

@@ -40,6 +40,29 @@ export const test_initial_state = (code, state) => {
) )
} }
export const test_async_calls_state = code => {
const {get_async_call, on_async_call} = (new Function(`
let call, calltree_changed_token
return {
get_async_call() {
return [call, calltree_changed_token]
},
on_async_call(_call, _calltree_changed_token) {
call = _call
calltree_changed_token = _calltree_changed_token
}
}
`))()
const state = test_initial_state(code, { on_async_call })
return {
state,
get_async_call,
on_async_call: state => COMMANDS.on_async_call(state, ...get_async_call())
}
}
export const stringify = val => export const stringify = val =>
JSON.stringify(val, (key, value) => { JSON.stringify(val, (key, value) => {
// TODO do not use instanceof because currently not implemented in parser // TODO do not use instanceof because currently not implemented in parser