diff --git a/src/runtime/multiversion.js b/src/runtime/multiversion.js index 88ae313..eea5e0b 100644 --- a/src/runtime/multiversion.js +++ b/src/runtime/multiversion.js @@ -19,25 +19,22 @@ function binarySearch(arr, el, compare_fn) { export class Multiversion { constructor(cxt, initial) { this.cxt = cxt - this.is_expanding_calltree_node = cxt.is_expanding_calltree_node + this.expand_calltree_node_number = cxt.expand_calltree_node_number this.latest = initial this.versions = [{version_number: cxt.version_counter, value: initial}] } + is_created_during_current_expand() { + return this.expand_calltree_node_number == this.cxt.expand_calltree_node_number + } + get() { if(!this.cxt.is_expanding_calltree_node) { return this.latest } else { - if(this.is_expanding_calltree_node) { - // var was created during current expansion, use its latest value + if(this.is_created_during_current_expand()) { return this.latest } else { - if(this.latest_copy != null) { - // value was set during expand_calltree_node, use this value - return this.latest - } - // TODO on first read, set latest and latest_copy? Note that it will - // interfere with at_moment_in_time const version_number = this.cxt.version_counter return this.get_version(version_number) } @@ -61,16 +58,11 @@ export class Multiversion { set(value) { const version_number = ++this.cxt.version_counter if(this.cxt.is_expanding_calltree_node) { - if(this.is_expanding_calltree_node) { + if(this.is_created_during_current_expand()) { this.latest = value this.set_version(version_number, value) - this.cxt.touched_multiversions.add(this) } else { - if(this.latest_copy == null) { - this.latest_copy = {value: this.latest} - } - this.cxt.touched_multiversions.add(this) - this.latest = value + // do nothing } } else { this.latest = value diff --git a/src/runtime/runtime.js b/src/runtime/runtime.js index 1d6df7b..43b7fae 100644 --- a/src/runtime/runtime.js +++ b/src/runtime/runtime.js @@ -194,7 +194,9 @@ export const set_record_call = cxt => { export const do_eval_expand_calltree_node = (cxt, node) => { cxt.is_recording_deferred_calls = false cxt.is_expanding_calltree_node = true - cxt.touched_multiversions = new Set() + cxt.expand_calltree_node_number = cxt.expand_calltree_node_number == null + ? 0 + : cxt.expand_calltree_node_number + 1 // Save call counter and set it to the value it had when executed 'fn' for // the first time @@ -227,16 +229,6 @@ export const do_eval_expand_calltree_node = (cxt, node) => { // Restore version_counter cxt.version_counter = version_counter - // Recover multiversions affected by expand_calltree_node - for(let m of cxt.touched_multiversions) { - if(m.is_expanding_calltree_node) { - delete m.is_expanding_calltree_node - } - if(m.latest_copy != null) { - m.latest = m.latest_copy.value - } - } - delete cxt.touched_multiversions cxt.is_expanding_calltree_node = false cxt.is_recording_deferred_calls = true diff --git a/test/test.js b/test/test.js index 886a84c..8960755 100644 --- a/test/test.js +++ b/test/test.js @@ -4682,4 +4682,32 @@ const y = x()` const moved = COMMANDS.move_cursor(expanded, code.indexOf('return x')) assert_equal(moved.value_explorer.result.value, 2) }), + + test('let_versions deferred calls get value', () => { + const code = ` + let x = 0 + + function noop() { + } + + function set(value) { + x = value + noop() + } + + set(1) + set(2) + set(3) + + export const get = () => x + ` + + const {state: i} = test_deferred_calls_state(code) + + const second_set_call = root_calltree_node(i).children[1] + assert_equal(second_set_call.has_more_children, true) + + const exp = COMMANDS.calltree.click(i, second_set_call.id) + assert_equal(exp.modules[''].get(), 3) + }), ]