0
0
mirror of https://github.com/vim/vim.git synced 2025-09-25 03:54:15 -04:00

patch 9.1.0369: Vim9: problem when importing autoloaded scripts

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>
This commit is contained in:
Ernie Rael
2024-04-24 20:07:50 +02:00
committed by Christian Brabandt
parent 04e8943556
commit 3f821d6de2
9 changed files with 137 additions and 8 deletions

View File

@@ -4235,6 +4235,7 @@ failed:
* - Whether the variable is read-only * - Whether the variable is read-only
* - Whether the variable value is locked * - Whether the variable value is locked
* - Whether the variable is locked * - Whether the variable is locked
* NOTE: "name" is only used for error messages.
*/ */
int int
var_check_permission(dictitem_T *di, char_u *name) var_check_permission(dictitem_T *di, char_u *name)

View File

@@ -381,6 +381,34 @@ def Test_disassemble_import_autoload()
v9.CheckScriptSuccess(lines) v9.CheckScriptSuccess(lines)
enddef 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() def s:ScriptFuncStore()
var localnr = 1 var localnr = 1
localnr = 2 localnr = 2

View File

@@ -166,6 +166,37 @@ def Test_wrong_function_name()
delfunc g:Define delfunc g:Define
enddef 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() def Test_listing_function_error()
var lines =<< trim END var lines =<< trim END
var filler = 123 var filler = 123

View File

@@ -1206,6 +1206,7 @@ def Test_autoload_export_variables()
mkdir('Xautoload_vars/autoload', 'pR') mkdir('Xautoload_vars/autoload', 'pR')
var lines =<< trim END var lines =<< trim END
vim9script vim9script
g:Xautoload_vars_autoload = true
export var val = 11 export var val = 11
val = 42 val = 42
END END
@@ -1215,13 +1216,24 @@ def Test_autoload_export_variables()
writefile(lines, 'Xautoload_vars/autoload/Xauto_vars_f2.vim', 'D') writefile(lines, 'Xautoload_vars/autoload/Xauto_vars_f2.vim', 'D')
lines =<< trim END lines =<< trim END
vim9script vim9script
g:Xautoload_vars_autoload = false
import autoload './Xautoload_vars/autoload/Xauto_vars_f2.vim' as f2 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 def F(): number
return f2.val return f2.val
enddef 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(42, F())
assert_equal(true, g:Xautoload_vars_autoload)
unlet g:Xautoload_vars_autoload
assert_equal(42, f2.val) assert_equal(42, f2.val)
f2.val = 17 f2.val = 17
assert_equal(17, f2.val) assert_equal(17, f2.val)
@@ -1264,6 +1276,44 @@ def Test_autoload_export_variables()
f4.val = 13 f4.val = 13
END END
v9.CheckScriptFailure(lines, 'E46:') 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 enddef
def Test_autoload_import_relative_autoload_dir() def Test_autoload_import_relative_autoload_dir()

View File

@@ -704,6 +704,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
369,
/**/ /**/
368, 368,
/**/ /**/

View File

@@ -780,6 +780,7 @@ typedef enum {
dest_vimvar, dest_vimvar,
dest_class_member, dest_class_member,
dest_script, dest_script,
dest_script_v9,
dest_reg, dest_reg,
dest_expr, dest_expr,
} assign_dest_T; } assign_dest_T;

View File

@@ -1367,6 +1367,7 @@ generate_loadvar(cctx_T *cctx, lhs_T *lhs)
generate_LOAD(cctx, ISN_LOADT, 0, name + 2, type); generate_LOAD(cctx, ISN_LOADT, 0, name + 2, type);
break; break;
case dest_script: case dest_script:
case dest_script_v9:
res = compile_load_scriptvar(cctx, res = compile_load_scriptvar(cctx,
name + (name[1] == ':' ? 2 : 0), NULL, NULL); name + (name[1] == ':' ? 2 : 0), NULL, NULL);
break; break;
@@ -1838,7 +1839,8 @@ compile_lhs(
return FAIL; 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 // existing script-local variables should have a type
lhs->lhs_scriptvar_sid = current_sctx.sc_sid; lhs->lhs_scriptvar_sid = current_sctx.sc_sid;
@@ -3026,6 +3028,7 @@ compile_assignment(
else else
{ {
if (is_decl && cmdidx == CMD_const && (lhs.lhs_dest == dest_script if (is_decl && cmdidx == CMD_const && (lhs.lhs_dest == dest_script
|| lhs.lhs_dest == dest_script_v9
|| lhs.lhs_dest == dest_global || lhs.lhs_dest == dest_global
|| lhs.lhs_dest == dest_local)) || lhs.lhs_dest == dest_local))
// ":const var": lock the value, but not referenced variables // ":const var": lock the value, but not referenced variables

View File

@@ -3842,11 +3842,19 @@ exec_instructions(ectx_T *ectx)
case ISN_STOREEXPORT: case ISN_STOREEXPORT:
{ {
int sid = iptr->isn_arg.loadstore.ls_sid; int sid = iptr->isn_arg.loadstore.ls_sid;
hashtab_T *ht = &SCRIPT_VARS(sid);
char_u *name = iptr->isn_arg.loadstore.ls_name; char_u *name = iptr->isn_arg.loadstore.ls_name;
dictitem_T *di = find_var_in_ht(ht, 0, dictitem_T *di = NULL;
iptr->isn_type == ISN_STORES // 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); ? name + 2 : name, TRUE);
}
--ectx->ec_stack.ga_len; --ectx->ec_stack.ga_len;
SOURCING_LNUM = iptr->isn_lnum; SOURCING_LNUM = iptr->isn_lnum;

View File

@@ -2394,6 +2394,7 @@ generate_store_var(
case dest_vimvar: case dest_vimvar:
return generate_STORE(cctx, ISN_STOREV, vimvaridx, NULL); return generate_STORE(cctx, ISN_STOREV, vimvaridx, NULL);
case dest_script: case dest_script:
case dest_script_v9:
{ {
int scriptvar_idx = lhs->lhs_scriptvar_idx; int scriptvar_idx = lhs->lhs_scriptvar_idx;
int scriptvar_sid = lhs->lhs_scriptvar_sid; int scriptvar_sid = lhs->lhs_scriptvar_sid;
@@ -2401,10 +2402,14 @@ generate_store_var(
{ {
isntype_T isn_type = ISN_STORES; 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) if (SCRIPT_ID_VALID(scriptvar_sid)
&& SCRIPT_ITEM(scriptvar_sid)->sn_import_autoload && SCRIPT_ITEM(scriptvar_sid)->sn_import_autoload
&& SCRIPT_ITEM(scriptvar_sid)->sn_autoload_prefix && ((SCRIPT_ITEM(scriptvar_sid)
== NULL) ->sn_autoload_prefix == NULL)
|| lhs->lhs_dest == dest_script_v9))
{ {
// "import autoload './dir/script.vim'" - load script // "import autoload './dir/script.vim'" - load script
// first // first