summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2022-01-12 19:54:00 +0000
committerBram Moolenaar <Bram@vim.org>2022-01-12 19:54:00 +0000
commitd041f4208b0a2149e9d41f6443aa1c14c076a411 (patch)
tree2fed762d017d9bae0177f03d021964b321db35f5
parent53c296112edd8471eb63afbca03f96bad164c813 (diff)
downloadvim-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.vim36
-rw-r--r--src/version.c2
-rw-r--r--src/vim9execute.c10
-rw-r--r--src/vim9expr.c24
-rw-r--r--src/vim9instr.c4
-rw-r--r--src/vim9script.c11
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
{