summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErnie Rael <errael@raelity.com>2024-04-24 20:07:50 +0200
committerChristian Brabandt <cb@256bit.org>2024-04-24 20:07:50 +0200
commit3f821d6de2586d921fb23e2facb4764ef9eb3294 (patch)
treec576910f877e4e43093a534172c1a4e7bdf329c4
parent04e8943556fbe2e53ce611f753141442bc8c655a (diff)
patch 9.1.0369: Vim9: problem when importing autoloaded scriptsv9.1.0369
Problem: Vim9: problem when importing autoloaded scripts Solution: In `:def` handle storing to vim9 autoload export (Ernie Rael) Problem occurs when `import autoload ./.../autoload/...`. The autoload in the specified path causes the use of an autoload_prefix which combines with the `import autoload` to create trouble. In `generate_store_var()` `case dest_script` use ISN_STOREEXPORT, when needed, instead of ISN_STORES. When executing ISN_STOREEXPORT, check for autoload_prefix. fixes: #14606 closes: #14615 Signed-off-by: Ernie Rael <errael@raelity.com> Signed-off-by: Christian Brabandt <cb@256bit.org> Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
-rw-r--r--src/evalvars.c1
-rw-r--r--src/testdir/test_vim9_disassemble.vim28
-rw-r--r--src/testdir/test_vim9_func.vim31
-rw-r--r--src/testdir/test_vim9_import.vim50
-rw-r--r--src/version.c2
-rw-r--r--src/vim9.h1
-rw-r--r--src/vim9compile.c9
-rw-r--r--src/vim9execute.c14
-rw-r--r--src/vim9instr.c9
9 files changed, 137 insertions, 8 deletions
diff --git a/src/evalvars.c b/src/evalvars.c
index b70a3cd394..6facbeb138 100644
--- a/src/evalvars.c
+++ b/src/evalvars.c
@@ -4235,6 +4235,7 @@ failed:
* - Whether the variable is read-only
* - Whether the variable value is locked
* - Whether the variable is locked
+ * NOTE: "name" is only used for error messages.
*/
int
var_check_permission(dictitem_T *di, char_u *name)
diff --git a/src/testdir/test_vim9_disassemble.vim b/src/testdir/test_vim9_disassemble.vim
index 92a4ff2a6e..c74cce4482 100644
--- a/src/testdir/test_vim9_disassemble.vim
+++ b/src/testdir/test_vim9_disassemble.vim
@@ -381,6 +381,34 @@ def Test_disassemble_import_autoload()
v9.CheckScriptSuccess(lines)
enddef
+def Test_disassemble_import_autoload_autoload()
+ mkdir('Xauto_auto/autoload', 'pR')
+ var lines =<< trim END
+ vim9script
+ export const val = 11
+ END
+ writefile(lines, 'Xauto_auto/autoload/Xauto_vars_f1.vim')
+
+ lines =<< trim END
+ vim9script
+
+ import autoload './Xauto_auto/autoload/Xauto_vars_f1.vim' as f1
+ def F()
+ f1.val = 13
+ enddef
+ var res = execute('disass F')
+
+ assert_match('<SNR>\d*_F.*' ..
+ 'f1.val = 13\_s*' ..
+ '\d PUSHNR 13\_s*' ..
+ '\d SOURCE .*/Xauto_auto/autoload/Xauto_vars_f1.vim\_s*' ..
+ '\d STOREEXPORT val in .*/Xauto_auto/autoload/Xauto_vars_f1.vim\_s*' ..
+ '\d RETURN void',
+ res)
+ END
+ v9.CheckScriptSuccess(lines)
+enddef
+
def s:ScriptFuncStore()
var localnr = 1
localnr = 2
diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim
index 27585a9049..b008929611 100644
--- a/src/testdir/test_vim9_func.vim
+++ b/src/testdir/test_vim9_func.vim
@@ -166,6 +166,37 @@ def Test_wrong_function_name()
delfunc g:Define
enddef
+" Check that in a legacy script a :def accesses the correct script variables.
+" Github issue: #14615.
+def Test_access_var_from_legacy_def()
+ # Access a script variable by name WITH "s:" prefix.
+ var lines =<< trim END
+ let s:foo = 'init'
+ let s:xxfoo = 'init'
+ def! AccessVarFromLegacyDef()
+ s:xxfoo = 'CHANGED'
+ enddef
+ call AccessVarFromLegacyDef()
+ call assert_equal('init', s:foo)
+ call assert_equal('CHANGED', s:xxfoo)
+ END
+ v9.CheckScriptSuccess(lines)
+
+ # Access a script variable by name WITHOUT "s:" prefix;
+ # previously this accessed "foo" and not "xxfoo"
+ lines =<< trim END
+ let s:foo = 'init'
+ let s:xxfoo = 'init'
+ def! AccessVarFromLegacyDef()
+ xxfoo = 'CHANGED'
+ enddef
+ call AccessVarFromLegacyDef()
+ call assert_equal('init', s:foo)
+ call assert_equal('CHANGED', s:xxfoo)
+ END
+ v9.CheckScriptSuccess(lines)
+enddef
+
def Test_listing_function_error()
var lines =<< trim END
var filler = 123
diff --git a/src/testdir/test_vim9_import.vim b/src/testdir/test_vim9_import.vim
index cfab50d584..581925d24c 100644
--- a/src/testdir/test_vim9_import.vim
+++ b/src/testdir/test_vim9_import.vim
@@ -1206,6 +1206,7 @@ def Test_autoload_export_variables()
mkdir('Xautoload_vars/autoload', 'pR')
var lines =<< trim END
vim9script
+ g:Xautoload_vars_autoload = true
export var val = 11
val = 42
END
@@ -1215,13 +1216,24 @@ def Test_autoload_export_variables()
writefile(lines, 'Xautoload_vars/autoload/Xauto_vars_f2.vim', 'D')
lines =<< trim END
vim9script
+ g:Xautoload_vars_autoload = false
import autoload './Xautoload_vars/autoload/Xauto_vars_f2.vim' as f2
+ # Verify that the import statement does not load the file.
+ assert_equal(false, g:Xautoload_vars_autoload)
def F(): number
return f2.val
enddef
+ # Verify compile does not load the file.
+ defcompile F
+ assert_equal(false, g:Xautoload_vars_autoload)
+
+ # load the file by accessing the exported variable
assert_equal(42, F())
+ assert_equal(true, g:Xautoload_vars_autoload)
+ unlet g:Xautoload_vars_autoload
+
assert_equal(42, f2.val)
f2.val = 17
assert_equal(17, f2.val)
@@ -1264,6 +1276,44 @@ def Test_autoload_export_variables()
f4.val = 13
END
v9.CheckScriptFailure(lines, 'E46:')
+
+ # Test const var is not modifiable from importing script from :def.
+ # Github issue: #14606
+ lines =<< trim END
+ vim9script
+ export const val = 11
+ END
+ writefile(lines, 'Xautoload_vars/autoload/Xauto_vars_f5.vim', 'D')
+ lines =<< trim END
+ vim9script
+
+ import autoload './Xautoload_vars/autoload/Xauto_vars_f5.vim' as f5
+
+ def F()
+ f5.val = 13
+ enddef
+ F()
+ END
+ v9.CheckScriptFailure(lines, 'E741:')
+
+ # Still part of Github issue: #14606
+ lines =<< trim END
+ vim9script
+ export var val = 11
+ END
+ writefile(lines, 'Xautoload_vars/autoload/Xauto_vars_f6.vim', 'D')
+ lines =<< trim END
+ vim9script
+
+ import autoload './Xautoload_vars/autoload/Xauto_vars_f6.vim' as f6
+
+ def F()
+ f6.val = 13
+ enddef
+ F()
+ assert_equal(13, f6.val)
+ END
+ v9.CheckScriptSuccess(lines)
enddef
def Test_autoload_import_relative_autoload_dir()
diff --git a/src/version.c b/src/version.c
index feed8385e5..658a410271 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 369,
+/**/
368,
/**/
367,
diff --git a/src/vim9.h b/src/vim9.h
index 65de618207..54938fe20c 100644
--- a/src/vim9.h
+++ b/src/vim9.h
@@ -780,6 +780,7 @@ typedef enum {
dest_vimvar,
dest_class_member,
dest_script,
+ dest_script_v9,
dest_reg,
dest_expr,
} assign_dest_T;
diff --git a/src/vim9compile.c b/src/vim9compile.c
index a091c57963..4cbc1cf058 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -1367,6 +1367,7 @@ generate_loadvar(cctx_T *cctx, lhs_T *lhs)
generate_LOAD(cctx, ISN_LOADT, 0, name + 2, type);
break;
case dest_script:
+ case dest_script_v9:
res = compile_load_scriptvar(cctx,
name + (name[1] == ':' ? 2 : 0), NULL, NULL);
break;
@@ -1838,7 +1839,8 @@ compile_lhs(
return FAIL;
}
- lhs->lhs_dest = dest_script;
+ lhs->lhs_dest = current_script_is_vim9()
+ ? dest_script_v9 : dest_script;
// existing script-local variables should have a type
lhs->lhs_scriptvar_sid = current_sctx.sc_sid;
@@ -3026,8 +3028,9 @@ compile_assignment(
else
{
if (is_decl && cmdidx == CMD_const && (lhs.lhs_dest == dest_script
- || lhs.lhs_dest == dest_global
- || lhs.lhs_dest == dest_local))
+ || lhs.lhs_dest == dest_script_v9
+ || lhs.lhs_dest == dest_global
+ || lhs.lhs_dest == dest_local))
// ":const var": lock the value, but not referenced variables
generate_LOCKCONST(cctx);
diff --git a/src/vim9execute.c b/src/vim9execute.c
index 5af3af68ba..3a3960a8d1 100644
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -3842,11 +3842,19 @@ exec_instructions(ectx_T *ectx)
case ISN_STOREEXPORT:
{
int sid = iptr->isn_arg.loadstore.ls_sid;
- hashtab_T *ht = &SCRIPT_VARS(sid);
char_u *name = iptr->isn_arg.loadstore.ls_name;
- dictitem_T *di = find_var_in_ht(ht, 0,
- iptr->isn_type == ISN_STORES
+ dictitem_T *di = NULL;
+ // First check for a variable from an exported autoload
+ // with an autoload_prefix; it would be in globals.
+ if (iptr->isn_type == ISN_STOREEXPORT)
+ di = find_var_autoload_prefix(name, sid, NULL, NULL);
+ // Then look for a variable in the script's variables.
+ if (di == NULL)
+ {
+ hashtab_T *ht = &SCRIPT_VARS(sid);
+ di = find_var_in_ht(ht, 0, STRNCMP("s:", name, 2) == 0
? name + 2 : name, TRUE);
+ }
--ectx->ec_stack.ga_len;
SOURCING_LNUM = iptr->isn_lnum;
diff --git a/src/vim9instr.c b/src/vim9instr.c
index 4df63fd09a..ad8beb1a30 100644
--- a/src/vim9instr.c
+++ b/src/vim9instr.c
@@ -2394,6 +2394,7 @@ generate_store_var(
case dest_vimvar:
return generate_STORE(cctx, ISN_STOREV, vimvaridx, NULL);
case dest_script:
+ case dest_script_v9:
{
int scriptvar_idx = lhs->lhs_scriptvar_idx;
int scriptvar_sid = lhs->lhs_scriptvar_sid;
@@ -2401,10 +2402,14 @@ generate_store_var(
{
isntype_T isn_type = ISN_STORES;
+ // If "sn_import_autoload", generate ISN_STOREEXPORT (not
+ // ISN_STORES) if destination is in a vim9script or if
+ // there is no "sn_autoload_prefix".
if (SCRIPT_ID_VALID(scriptvar_sid)
&& SCRIPT_ITEM(scriptvar_sid)->sn_import_autoload
- && SCRIPT_ITEM(scriptvar_sid)->sn_autoload_prefix
- == NULL)
+ && ((SCRIPT_ITEM(scriptvar_sid)
+ ->sn_autoload_prefix == NULL)
+ || lhs->lhs_dest == dest_script_v9))
{
// "import autoload './dir/script.vim'" - load script
// first