mirror of
https://github.com/leporello-js/leporello-js
synced 2026-01-13 13:04:30 -08:00
fix parse
This commit is contained in:
40
src/cmd.js
40
src/cmd.js
@@ -74,35 +74,14 @@ const run_code = (s, globals) => {
|
|||||||
? globals == null
|
? globals == null
|
||||||
: set_is_eq(s.globals, globals)
|
: set_is_eq(s.globals, globals)
|
||||||
|
|
||||||
const parse_result = load_modules(s.entrypoint, module => {
|
// If globals change, then errors for using undeclared identifiers may be
|
||||||
if(s.dirty_files != null && s.dirty_files.has(module)) {
|
// no longer valid. Do not use cache
|
||||||
return s.files[module]
|
const parse_cache = is_globals_eq ? s.parse_result.cache : {}
|
||||||
}
|
const loader = module => s.files[module]
|
||||||
|
const parse_result = load_modules(s.entrypoint, loader, parse_cache, globals)
|
||||||
// If globals change, then errors for using undeclared identifiers may be
|
|
||||||
// no longer valid. Do not use cache
|
|
||||||
if(is_globals_eq) {
|
|
||||||
const result = s.parse_result.cache[module]
|
|
||||||
if(result != null) {
|
|
||||||
return result
|
|
||||||
} else {
|
|
||||||
return s.files[module]
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return s.files[module]
|
|
||||||
}
|
|
||||||
|
|
||||||
}, globals)
|
|
||||||
|
|
||||||
const dirty_files = new Set(
|
|
||||||
[...(s.dirty_files ?? new Set())].filter(file =>
|
|
||||||
parse_result.modules[file] == null
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
const state = {
|
const state = {
|
||||||
...s,
|
...s,
|
||||||
dirty_files,
|
|
||||||
globals,
|
globals,
|
||||||
parse_result,
|
parse_result,
|
||||||
calltree: null,
|
calltree: null,
|
||||||
@@ -255,7 +234,14 @@ const input = (state, code, index) => {
|
|||||||
const with_files = {
|
const with_files = {
|
||||||
...state,
|
...state,
|
||||||
files,
|
files,
|
||||||
dirty_files: new Set([...(state.dirty_files ?? []), state.current_module])
|
parse_result: state.parse_result == null
|
||||||
|
? null
|
||||||
|
: {
|
||||||
|
...state.parse_result,
|
||||||
|
cache: filter_object(state.parse_result.cache, module =>
|
||||||
|
module != state.current_module
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const next = set_cursor_position(with_files, index)
|
const next = set_cursor_position(with_files, index)
|
||||||
const effect_save = {
|
const effect_save = {
|
||||||
|
|||||||
@@ -1774,16 +1774,16 @@ export const print_debug_node = node => {
|
|||||||
return stringify(do_print_debug_node(node))
|
return stringify(do_print_debug_node(node))
|
||||||
}
|
}
|
||||||
|
|
||||||
const do_load_modules = (module_names, loader, already_loaded, globals) => {
|
const do_load_modules = (module_names, loader, already_loaded, parse_cache, globals) => {
|
||||||
const parsed = module_names
|
const parsed = module_names
|
||||||
.filter(module_name => already_loaded[module_name] == null)
|
.filter(module_name => already_loaded[module_name] == null)
|
||||||
.map(module_name => {
|
.map(module_name => {
|
||||||
|
if(parse_cache[module_name] != null) {
|
||||||
|
return [module_name, parse_cache[module_name]]
|
||||||
|
}
|
||||||
const m = loader(module_name)
|
const m = loader(module_name)
|
||||||
if(m == null) {
|
if(m == null) {
|
||||||
return [module_name, {ok: false, problems: [{is_load_error: true}]}]
|
return [module_name, {ok: false, problems: [{is_load_error: true}]}]
|
||||||
} else if(typeof(m) == 'object' && m.ok != null) {
|
|
||||||
// Allows cache parse result
|
|
||||||
return [module_name, m]
|
|
||||||
} else if(typeof(m) == 'string') {
|
} else if(typeof(m) == 'string') {
|
||||||
return [module_name, parse(m, globals, true, module_name)]
|
return [module_name, parse(m, globals, true, module_name)]
|
||||||
} else {
|
} else {
|
||||||
@@ -1831,6 +1831,7 @@ const do_load_modules = (module_names, loader, already_loaded, globals) => {
|
|||||||
deps,
|
deps,
|
||||||
loader,
|
loader,
|
||||||
{...already_loaded, ...modules},
|
{...already_loaded, ...modules},
|
||||||
|
parse_cache,
|
||||||
globals
|
globals
|
||||||
)
|
)
|
||||||
if(loaded_deps.ok) {
|
if(loaded_deps.ok) {
|
||||||
@@ -1874,11 +1875,11 @@ const do_load_modules = (module_names, loader, already_loaded, globals) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const load_modules = (entry_module, loader, globals) => {
|
export const load_modules = (entry_module, loader, parse_cache, globals) => {
|
||||||
// TODO check_imports. detect cycles while modules are loading, in
|
// TODO check_imports. detect cycles while modules are loading, in
|
||||||
// do_load_modules
|
// do_load_modules
|
||||||
|
|
||||||
const result = do_load_modules([entry_module], loader, {}, globals)
|
const result = do_load_modules([entry_module], loader, {}, parse_cache, globals)
|
||||||
if(!result.ok) {
|
if(!result.ok) {
|
||||||
return result
|
return result
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1013,7 +1013,6 @@ export const tests = [
|
|||||||
|
|
||||||
// change module ''
|
// change module ''
|
||||||
const {state: s2} = input(spoil_file, 'import {c} from "c"', 0)
|
const {state: s2} = input(spoil_file, 'import {c} from "c"', 0)
|
||||||
assert_equal(s2.dirty_files, new Set())
|
|
||||||
|
|
||||||
assert_equal(s2.parse_result.ok, true)
|
assert_equal(s2.parse_result.ok, true)
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ export const parse_modules = (entry, modules) =>
|
|||||||
load_modules(
|
load_modules(
|
||||||
entry,
|
entry,
|
||||||
module_name => modules[module_name],
|
module_name => modules[module_name],
|
||||||
|
{},
|
||||||
new Set(Object.getOwnPropertyNames(globalThis.app_window))
|
new Set(Object.getOwnPropertyNames(globalThis.app_window))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user