mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
patch 9.1.0360: Vim9: does not handle autoloaded variables well
Problem: Vim9: does not handle autoloaded variables well Solution: Better handle script-level exported variable references from autoload files (Ernie Rael). fixes: #14591 closes: #14607 Signed-off-by: Ernie Rael <errael@raelity.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
parent
158673680f
commit
84f6dc7ed2
@ -3340,12 +3340,31 @@ find_var(char_u *name, hashtab_T **htp, int no_autoload)
|
||||
}
|
||||
}
|
||||
|
||||
// and finally try
|
||||
return find_var_autoload_prefix(name, 0, htp, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find variable "name" with sn_autoload_prefix.
|
||||
* Return a pointer to it if found, NULL if not found.
|
||||
* When "sid" > 0, use it otherwise use "current_sctx.sc_sid".
|
||||
* When "htp" is not NULL set "htp" to the hashtab_T used.
|
||||
* When "namep" is not NULL set "namep" to the generated name, and
|
||||
* then the caller gets ownership and is responsible for freeing the name.
|
||||
*/
|
||||
dictitem_T *
|
||||
find_var_autoload_prefix(char_u *name, int sid, hashtab_T **htp,
|
||||
char_u **namep)
|
||||
{
|
||||
hashtab_T *ht;
|
||||
dictitem_T *ret = NULL;
|
||||
// When using "vim9script autoload" script-local items are prefixed but can
|
||||
// be used with s:name.
|
||||
if (SCRIPT_ID_VALID(current_sctx.sc_sid)
|
||||
int check_sid = sid > 0 ? sid : current_sctx.sc_sid;
|
||||
if (SCRIPT_ID_VALID(check_sid)
|
||||
&& (in_vim9script() || (name[0] == 's' && name[1] == ':')))
|
||||
{
|
||||
scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
|
||||
scriptitem_T *si = SCRIPT_ITEM(check_sid);
|
||||
|
||||
if (si->sn_autoload_prefix != NULL)
|
||||
{
|
||||
@ -3355,20 +3374,26 @@ find_var(char_u *name, hashtab_T **htp, int no_autoload)
|
||||
|
||||
if (auto_name != NULL)
|
||||
{
|
||||
int free_auto_name = TRUE;
|
||||
ht = &globvarht;
|
||||
ret = find_var_in_ht(ht, 'g', auto_name, TRUE);
|
||||
vim_free(auto_name);
|
||||
if (ret != NULL)
|
||||
{
|
||||
if (htp != NULL)
|
||||
*htp = ht;
|
||||
return ret;
|
||||
if (namep != NULL)
|
||||
{
|
||||
free_auto_name = FALSE;
|
||||
*namep = auto_name;
|
||||
}
|
||||
}
|
||||
if (free_auto_name)
|
||||
vim_free(auto_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3508,7 +3533,11 @@ lookup_scriptitem(
|
||||
hi = hash_find(ht, p);
|
||||
res = HASHITEM_EMPTY(hi) ? FAIL : OK;
|
||||
|
||||
// if not script-local, then perhaps imported
|
||||
// if not script-local, then perhaps autoload-exported
|
||||
if (res == FAIL && find_var_autoload_prefix(p, 0, NULL, NULL) != NULL)
|
||||
res = OK;
|
||||
|
||||
// if not script-local or autoload, then perhaps imported
|
||||
if (res == FAIL && find_imported(p, 0, FALSE) != NULL)
|
||||
res = OK;
|
||||
if (p != buffer)
|
||||
@ -3904,23 +3933,40 @@ set_var_const(
|
||||
|
||||
if (sid != 0)
|
||||
{
|
||||
varname = NULL;
|
||||
if (SCRIPT_ID_VALID(sid))
|
||||
ht = &SCRIPT_VARS(sid);
|
||||
varname = name;
|
||||
{
|
||||
char_u *auto_name = NULL;
|
||||
if (find_var_autoload_prefix(name, sid, &ht, &auto_name) != NULL)
|
||||
{
|
||||
var_in_autoload = TRUE;
|
||||
varname = auto_name;
|
||||
name_tofree = varname;
|
||||
}
|
||||
else
|
||||
ht = &SCRIPT_VARS(sid);
|
||||
}
|
||||
if (varname == NULL)
|
||||
varname = name;
|
||||
}
|
||||
else
|
||||
{
|
||||
scriptitem_T *si;
|
||||
scriptitem_T *si;
|
||||
char_u *auto_name = NULL;
|
||||
|
||||
if (in_vim9script() && is_export
|
||||
&& SCRIPT_ID_VALID(current_sctx.sc_sid)
|
||||
&& (si = SCRIPT_ITEM(current_sctx.sc_sid))
|
||||
->sn_autoload_prefix != NULL)
|
||||
if (in_vim9script()
|
||||
&& SCRIPT_ID_VALID(current_sctx.sc_sid)
|
||||
&& (si = SCRIPT_ITEM(current_sctx.sc_sid))
|
||||
->sn_autoload_prefix != NULL
|
||||
&& (is_export
|
||||
|| find_var_autoload_prefix(name, 0, NULL, &auto_name)
|
||||
!= NULL))
|
||||
{
|
||||
// In a vim9 autoload script an exported variable is put in the
|
||||
// global namespace with the autoload prefix.
|
||||
var_in_autoload = TRUE;
|
||||
varname = concat_str(si->sn_autoload_prefix, name);
|
||||
varname = auto_name != NULL ? auto_name
|
||||
: concat_str(si->sn_autoload_prefix, name);
|
||||
if (varname == NULL)
|
||||
goto failed;
|
||||
name_tofree = varname;
|
||||
|
@ -63,6 +63,7 @@ int eval_variable(char_u *name, int len, scid_T sid, typval_T *rettv, dictitem_T
|
||||
int eval_variable_import(char_u *name, typval_T *rettv);
|
||||
void check_vars(char_u *name, int len);
|
||||
dictitem_T *find_var(char_u *name, hashtab_T **htp, int no_autoload);
|
||||
dictitem_T *find_var_autoload_prefix(char_u *name, int sid, hashtab_T **htp, char_u **namep);
|
||||
dictitem_T *find_var_also_in_script(char_u *name, hashtab_T **htp, int no_autoload);
|
||||
dictitem_T *find_var_in_ht(hashtab_T *ht, int htname, char_u *varname, int no_autoload);
|
||||
hashtab_T *get_script_local_ht(void);
|
||||
|
@ -1201,6 +1201,71 @@ def Test_autoload_import_relative_from_buffer_in_dir()
|
||||
:bw!
|
||||
enddef
|
||||
|
||||
" Test modifying exported autoload variable. Github issue: #14591
|
||||
def Test_autoload_export_variables()
|
||||
mkdir('Xautoload_vars/autoload', 'pR')
|
||||
var lines =<< trim END
|
||||
vim9script
|
||||
export var val = 11
|
||||
val = 42
|
||||
END
|
||||
|
||||
# Test that the imported script, above, can modify the exported variable;
|
||||
# and test that the importing script, below, can modify the variable.
|
||||
writefile(lines, 'Xautoload_vars/autoload/Xauto_vars_f2.vim', 'D')
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
|
||||
import autoload './Xautoload_vars/autoload/Xauto_vars_f2.vim' as f2
|
||||
|
||||
def F(): number
|
||||
return f2.val
|
||||
enddef
|
||||
assert_equal(42, F())
|
||||
assert_equal(42, f2.val)
|
||||
f2.val = 17
|
||||
assert_equal(17, f2.val)
|
||||
|
||||
def G()
|
||||
f2.val = 19
|
||||
enddef
|
||||
G()
|
||||
assert_equal(19, f2.val)
|
||||
END
|
||||
v9.CheckScriptSuccess(lines)
|
||||
|
||||
# Test const var is not modifiable.
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
export const val = 11
|
||||
val = 42
|
||||
END
|
||||
writefile(lines, 'Xautoload_vars/autoload/Xauto_vars_f3.vim', 'D')
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
|
||||
import autoload './Xautoload_vars/autoload/Xauto_vars_f3.vim' as f3
|
||||
|
||||
var x = f3.val
|
||||
END
|
||||
v9.CheckScriptFailure(lines, 'E46:')
|
||||
|
||||
# Test const var is not modifiable from importing script.
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
export const val = 11
|
||||
END
|
||||
writefile(lines, 'Xautoload_vars/autoload/Xauto_vars_f4.vim', 'D')
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
|
||||
import autoload './Xautoload_vars/autoload/Xauto_vars_f4.vim' as f4
|
||||
|
||||
f4.val = 13
|
||||
END
|
||||
v9.CheckScriptFailure(lines, 'E46:')
|
||||
enddef
|
||||
|
||||
def Test_autoload_import_relative_autoload_dir()
|
||||
mkdir('autoload', 'pR')
|
||||
var lines =<< trim END
|
||||
|
@ -704,6 +704,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
360,
|
||||
/**/
|
||||
359,
|
||||
/**/
|
||||
|
Loading…
x
Reference in New Issue
Block a user