diff options
author | Bram Moolenaar <Bram@vim.org> | 2022-01-12 19:54:00 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2022-01-12 19:54:00 +0000 |
commit | d041f4208b0a2149e9d41f6443aa1c14c076a411 (patch) | |
tree | 2fed762d017d9bae0177f03d021964b321db35f5 | |
parent | 53c296112edd8471eb63afbca03f96bad164c813 (diff) | |
download | vim-git-8.2.4072.tar.gz |
patch 8.2.4072: Vim9: compiling function fails when autoload is not loadedv8.2.4072
Problem: Vim9: compiling function fails when autoload script is not loaded
yet.
Solution: Depend on runtime loading.
-rw-r--r-- | src/testdir/test_vim9_import.vim | 36 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim9execute.c | 10 | ||||
-rw-r--r-- | src/vim9expr.c | 24 | ||||
-rw-r--r-- | src/vim9instr.c | 4 | ||||
-rw-r--r-- | src/vim9script.c | 11 |
6 files changed, 83 insertions, 4 deletions
diff --git a/src/testdir/test_vim9_import.vim b/src/testdir/test_vim9_import.vim index bfc99d531..922bd3d66 100644 --- a/src/testdir/test_vim9_import.vim +++ b/src/testdir/test_vim9_import.vim @@ -1218,6 +1218,42 @@ def Test_vim9script_autoload_call() &rtp = save_rtp enddef +def Test_import_autoload_postponed() + mkdir('Xdir/autoload', 'p') + var save_rtp = &rtp + exe 'set rtp^=' .. getcwd() .. '/Xdir' + + var lines =<< trim END + vim9script autoload + + g:loaded_postponed = 'true' + export var variable = 'bla' + export def Function(): string + return 'bla' + enddef + END + writefile(lines, 'Xdir/autoload/postponed.vim') + + lines =<< trim END + vim9script + + import autoload 'postponed.vim' + def Tryit() + echo postponed.variable + echo postponed.Function() + enddef + defcompile + END + CheckScriptSuccess(lines) + assert_false(exists('g:loaded_postponed')) + CheckScriptSuccess(lines + ['Tryit()']) + assert_equal('true', g:loaded_postponed) + + unlet g:loaded_postponed + delete('Xdir', 'rf') + &rtp = save_rtp +enddef + def Test_autoload_mapping() mkdir('Xdir/autoload', 'p') var save_rtp = &rtp diff --git a/src/version.c b/src/version.c index 2a1b4ae5e..12097729f 100644 --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 4072, +/**/ 4071, /**/ 4070, diff --git a/src/vim9execute.c b/src/vim9execute.c index 311baca01..ba810680c 100644 --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -2227,6 +2227,16 @@ exec_instructions(ectx_T *ectx) } di = find_var_in_ht(ht, 0, iptr->isn_arg.string, TRUE); + if (di == NULL && ht == get_globvar_ht()) + { + // may need to load autoload script + if (script_autoload(iptr->isn_arg.string, FALSE)) + di = find_var_in_ht(ht, 0, + iptr->isn_arg.string, TRUE); + if (did_emsg) + goto on_error; + } + if (di == NULL) { SOURCING_LNUM = iptr->isn_lnum; diff --git a/src/vim9expr.c b/src/vim9expr.c index f12acf65a..400bad6fd 100644 --- a/src/vim9expr.c +++ b/src/vim9expr.c @@ -274,6 +274,8 @@ compile_load_scriptvar( int cc; ufunc_T *ufunc; type_T *type; + int done = FALSE; + int res = OK; // TODO: if this is an autoload import do something else. // Need to lookup the member. @@ -296,11 +298,31 @@ compile_load_scriptvar( cc = *p; *p = NUL; - idx = find_exported(import->imp_sid, exp_name, &ufunc, &type, + si = SCRIPT_ITEM(import->imp_sid); + if (si->sn_autoload_prefix != NULL + && si->sn_state == SN_STATE_NOT_LOADED) + { + char_u *auto_name = concat_str(si->sn_autoload_prefix, exp_name); + + // autoload script must be loaded later, access by the autoload + // name. + if (cc == '(') + res = generate_PUSHFUNC(cctx, auto_name, &t_func_any); + else + res = generate_LOAD(cctx, ISN_LOADG, 0, auto_name, &t_any); + vim_free(auto_name); + done = TRUE; + } + else + { + idx = find_exported(import->imp_sid, exp_name, &ufunc, &type, cctx, TRUE); + } *p = cc; p = skipwhite(p); *end = p; + if (done) + return res; if (idx < 0) { diff --git a/src/vim9instr.c b/src/vim9instr.c index 8ce32a766..48b22a6d7 100644 --- a/src/vim9instr.c +++ b/src/vim9instr.c @@ -714,7 +714,6 @@ generate_PUSHBLOB(cctx_T *cctx, blob_T *blob) /* * Generate an ISN_PUSHFUNC instruction with name "name". - * Consumes "name". */ int generate_PUSHFUNC(cctx_T *cctx, char_u *name, type_T *type) @@ -727,7 +726,8 @@ generate_PUSHFUNC(cctx_T *cctx, char_u *name, type_T *type) return FAIL; if (name == NULL) funcname = NULL; - else if (*name == K_SPECIAL) // script-local + else if (*name == K_SPECIAL // script-local + || vim_strchr(name, AUTOLOAD_CHAR) != NULL) // autoload funcname = vim_strsave(name); else { diff --git a/src/vim9script.c b/src/vim9script.c index b72995c11..6d02be6ad 100644 --- a/src/vim9script.c +++ b/src/vim9script.c @@ -488,7 +488,16 @@ handle_import( // we need a scriptitem without loading the script sid = find_script_in_rtp(from_name); vim_free(from_name); - res = SCRIPT_ID_VALID(sid) ? OK : FAIL; + if (SCRIPT_ID_VALID(sid)) + { + scriptitem_T *si = SCRIPT_ITEM(sid); + + if (si->sn_autoload_prefix == NULL) + si->sn_autoload_prefix = get_autoload_prefix(si); + res = OK; + } + else + res = FAIL; } else { |