This commit is contained in:
Dmitry Vasilev
2024-02-05 04:13:02 +08:00
parent e1f7dd437c
commit 14627ad187
8 changed files with 53 additions and 72 deletions

View File

@@ -534,6 +534,13 @@ const change_html_file = (state, html_file) => {
return {...state, html_file}
}
const goto_location = (state, loc) => {
return {
state: move_cursor(set_location(state, loc), loc.index),
effects: {type: 'set_focus'},
}
}
const goto_definition = (state, index) => {
if(!state.parse_result.ok){
return {state, effects: {type: 'set_status', args: ['unresolved syntax errors']}}
@@ -569,12 +576,7 @@ const goto_definition = (state, index) => {
} else {
loc = {module: state.current_module, index: d.index}
}
return {
state: move_cursor(
{...state, current_module: loc.module},
loc.index,
)
}
return goto_location(state, loc)
}
}
}
@@ -950,6 +952,7 @@ export const COMMANDS = {
change_current_module,
change_entrypoint,
change_html_file,
goto_location,
goto_definition,
goto_problem,
move_cursor,

View File

@@ -1,19 +1,11 @@
import {exec} from '../index.js'
import {el, stringify, fn_link, scrollIntoViewIfNeeded} from './domutils.js'
import {el, scrollIntoViewIfNeeded, value_to_dom_el, join} from './domutils.js'
import {stringify_for_header} from '../value_explorer_utils.js'
import {find_node} from '../ast_utils.js'
import {with_version_number} from '../runtime/runtime.js'
import {is_expandable, root_calltree_node, get_deferred_calls, has_error}
from '../calltree.js'
// TODO perf - quadratic difficulty
const join = arr => arr.reduce(
(acc, el) => acc.length == 0
? [el]
: [...acc, ',', el],
[],
)
export class CallTree {
constructor(ui, container) {
this.ui = ui
@@ -111,11 +103,7 @@ export class CallTree {
...join(
// for arguments, use n.version_number - last version before call
with_version_number(this.state.rt_cxt, n.version_number, () =>
n.args.map(
a => typeof(a) == 'function'
? fn_link(a)
: stringify_for_header(a)
)
n.args.map(a => value_to_dom_el(a))
)
),
')' ,
@@ -124,7 +112,9 @@ export class CallTree {
// for return value, use n.last_version_number - last version that was
// created during call
with_version_number(this.state.rt_cxt, n.last_version_number, () =>
(n.ok ? stringify_for_header(n.value) : stringify_for_header(n.error))
n.ok
? value_to_dom_el(n.value)
: stringify_for_header(n.error)
)
),
),

View File

@@ -1,3 +1,6 @@
import {exec} from '../index.js'
import {stringify_for_header} from '../value_explorer_utils.js'
export function el(tag, className, ...children){
const result = document.createElement(tag)
if(typeof(className) == 'string'){
@@ -38,38 +41,40 @@ export function el(tag, className, ...children){
return result
}
export function stringify(val){
function fn_to_str(fn){
// TODO if name is 'anonymous', then change name for code
return fn.__location == null
? `<span>${fn.name}</span>`
: `<a
href='javascript:void(0)'
data-location=${JSON.stringify(fn.__location)}
><i>fn</i> ${fn.name}</a>`
}
if(typeof(val) == 'undefined') {
return 'undefined'
} else if(typeof(val) == 'function'){
return fn_to_str(val)
} else {
return JSON.stringify(val, (key, value) => {
if(typeof(value) == 'function'){
return fn_to_str(value)
} else {
return value
}
})
}
}
export function fn_link(fn){
const str = stringify(fn)
function fn_link(fn){
// TODO if name is empty or 'anonymous', then show its source code instead
// of name
const str = fn.__location == null
? `<span>${fn.name}</span>`
: `<a href='javascript:void(0)'><i>fn</i> ${fn.name}</a>`
const c = document.createElement('div')
c.innerHTML = str
return c.children[0]
const el = c.children[0]
if(fn.__location != null) {
el.addEventListener('click', e => {
e.stopPropagation()
exec('goto_location',fn.__location)
})
}
return el
}
export function value_to_dom_el(value) {
return typeof(value) == 'function'
? fn_link(value)
: stringify_for_header(value)
}
export function join(arr, separator = ', ') {
const result = []
for(let i = 0; i < arr.length; i++) {
result.push(arr[i])
if(i != arr.length - 1) {
result.push(separator)
}
}
return result
}
// Idea is borrowed from:

View File

@@ -1,7 +1,7 @@
import {exec, get_state} from '../index.js'
import {ValueExplorer} from './value_explorer.js'
import {stringify_for_header} from '../value_explorer_utils.js'
import {el, stringify, fn_link} from './domutils.js'
import {el} from './domutils.js'
import {version_number_symbol} from '../calltree.js'
/*

View File

@@ -55,7 +55,6 @@ export class IO_Trace {
+ (is_used ? '' : 'native '),
item.name,
'(' ,
// TODO fn_link, like in ./calltree.js
item.args.map(a => header(a)).join(', '),
'): ' ,
(item.ok ? stringify_for_header(item.value) : item.error.toString())

View File

@@ -1,4 +1,4 @@
import {el, scrollIntoViewIfNeeded} from './domutils.js'
import {el, scrollIntoViewIfNeeded, value_to_dom_el, join} from './domutils.js'
import {exec} from '../index.js'
import {header} from '../value_explorer_utils.js'
import {with_version_number_of_log} from '../cmd.js'
@@ -72,10 +72,9 @@ export class Logs {
+ ':'
),
' ',
with_version_number_of_log(state, log, () =>
// TODO fn_link, for function args, like in ./calltree.js
log.args.map(a => header(a)).join(', ')
)
...join(with_version_number_of_log(state, log, () =>
log.args.map(a => value_to_dom_el(a))
))
)
)
}

View File

@@ -171,21 +171,6 @@ export class UI {
this.logs = new Logs(this, this.debugger.logs)
this.io_trace = new IO_Trace(this, this.debugger.io_trace)
// TODO jump to another module
// TODO use exec
const jump_to_fn_location = (e) => {
let loc
if((loc = e.target.dataset.location) != null){
loc = JSON.parse(loc)
this.editor.set_cursor_position(loc.index)
this.editor.focus()
}
}
// TODO when click in calltree, do not jump to location, navigateCallTree
// instead
this.debugger.calltree.addEventListener('click', jump_to_fn_location)
this.render_current_module(state.current_module)
this.set_active_tab('calltree', true)

View File

@@ -3,7 +3,7 @@
// TODO fns as clickable links (jump to definition), both for header and for
// content
import {el, stringify, scrollIntoViewIfNeeded} from './domutils.js'
import {el, scrollIntoViewIfNeeded} from './domutils.js'
import {with_code_execution} from '../index.js'
// TODO remove is_expandble, join with displayed entries
import {header, short_header, is_expandable, displayed_entries} from '../value_explorer_utils.js'