mirror of
https://github.com/leporello-js/leporello-js
synced 2026-01-13 13:04:30 -08:00
refactor
This commit is contained in:
15
src/cmd.js
15
src/cmd.js
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
)
|
||||
),
|
||||
),
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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'
|
||||
|
||||
/*
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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))
|
||||
))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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'
|
||||
|
||||
Reference in New Issue
Block a user