0
0
mirror of https://github.com/vim/vim.git synced 2025-11-15 23:14:06 -05:00

patch 8.2.1510: using "var" in :def function may refer to legacy script var

Problem:    Using "var" in a :def function may refer to a legacy Vim script
            variable.
Solution:   Require using "s:" to refer to a legacy Vim script variable.
            (closes #6771)
This commit is contained in:
Bram Moolenaar
2020-08-22 19:02:02 +02:00
parent 9943b3d979
commit 5390099a97
3 changed files with 33 additions and 27 deletions

View File

@@ -829,30 +829,30 @@ endfunc
let s:funcResult = 0 let s:funcResult = 0
def FuncNoArgNoRet() def FuncNoArgNoRet()
funcResult = 11 s:funcResult = 11
enddef enddef
def FuncNoArgRetNumber(): number def FuncNoArgRetNumber(): number
funcResult = 22 s:funcResult = 22
return 1234 return 1234
enddef enddef
def FuncNoArgRetString(): string def FuncNoArgRetString(): string
funcResult = 45 s:funcResult = 45
return 'text' return 'text'
enddef enddef
def FuncOneArgNoRet(arg: number) def FuncOneArgNoRet(arg: number)
funcResult = arg s:funcResult = arg
enddef enddef
def FuncOneArgRetNumber(arg: number): number def FuncOneArgRetNumber(arg: number): number
funcResult = arg s:funcResult = arg
return arg return arg
enddef enddef
def FuncTwoArgNoRet(one: bool, two: number) def FuncTwoArgNoRet(one: bool, two: number)
funcResult = two s:funcResult = two
enddef enddef
def FuncOneArgRetString(arg: string): string def FuncOneArgRetString(arg: string): string
@@ -865,31 +865,31 @@ enddef
def Test_func_type() def Test_func_type()
let Ref1: func() let Ref1: func()
funcResult = 0 s:funcResult = 0
Ref1 = FuncNoArgNoRet Ref1 = FuncNoArgNoRet
Ref1() Ref1()
assert_equal(11, funcResult) assert_equal(11, s:funcResult)
let Ref2: func let Ref2: func
funcResult = 0 s:funcResult = 0
Ref2 = FuncNoArgNoRet Ref2 = FuncNoArgNoRet
Ref2() Ref2()
assert_equal(11, funcResult) assert_equal(11, s:funcResult)
funcResult = 0 s:funcResult = 0
Ref2 = FuncOneArgNoRet Ref2 = FuncOneArgNoRet
Ref2(12) Ref2(12)
assert_equal(12, funcResult) assert_equal(12, s:funcResult)
funcResult = 0 s:funcResult = 0
Ref2 = FuncNoArgRetNumber Ref2 = FuncNoArgRetNumber
assert_equal(1234, Ref2()) assert_equal(1234, Ref2())
assert_equal(22, funcResult) assert_equal(22, s:funcResult)
funcResult = 0 s:funcResult = 0
Ref2 = FuncOneArgRetNumber Ref2 = FuncOneArgRetNumber
assert_equal(13, Ref2(13)) assert_equal(13, Ref2(13))
assert_equal(13, funcResult) assert_equal(13, s:funcResult)
enddef enddef
def Test_repeat_return_type() def Test_repeat_return_type()

View File

@@ -754,6 +754,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 */
/**/
1510,
/**/ /**/
1509, 1509,
/**/ /**/

View File

@@ -260,15 +260,20 @@ lookup_arg(
/* /*
* Lookup a variable in the current script. * Lookup a variable in the current script.
* If "vim9script" is TRUE the script must be Vim9 script. Used for "var"
* without "s:".
* Returns OK or FAIL. * Returns OK or FAIL.
*/ */
static int static int
lookup_script(char_u *name, size_t len) lookup_script(char_u *name, size_t len, int vim9script)
{ {
int cc; int cc;
hashtab_T *ht = &SCRIPT_VARS(current_sctx.sc_sid); hashtab_T *ht = &SCRIPT_VARS(current_sctx.sc_sid);
dictitem_T *di; dictitem_T *di;
if (vim9script && SCRIPT_ITEM(current_sctx.sc_sid)->sn_version
!= SCRIPT_VERSION_VIM9)
return FAIL;
cc = name[len]; cc = name[len];
name[len] = NUL; name[len] = NUL;
di = find_var_in_ht(ht, 0, name, TRUE); di = find_var_in_ht(ht, 0, name, TRUE);
@@ -287,7 +292,7 @@ check_defined(char_u *p, size_t len, cctx_T *cctx)
int c = p[len]; int c = p[len];
p[len] = NUL; p[len] = NUL;
if (lookup_script(p, len) == OK if (lookup_script(p, len, FALSE) == OK
|| (cctx != NULL || (cctx != NULL
&& (lookup_local(p, len, cctx) != NULL && (lookup_local(p, len, cctx) != NULL
|| lookup_arg(p, len, NULL, NULL, NULL, cctx) == OK)) || lookup_arg(p, len, NULL, NULL, NULL, cctx) == OK))
@@ -2145,15 +2150,14 @@ compile_load(char_u **arg, char_u *end_arg, cctx_T *cctx, int error)
else else
{ {
// "var" can be script-local even without using "s:" if it // "var" can be script-local even without using "s:" if it
// already exists. // already exists in a Vim9 script or when it's imported.
if (SCRIPT_ITEM(current_sctx.sc_sid)->sn_version if (lookup_script(*arg, len, TRUE) == OK
== SCRIPT_VERSION_VIM9 || find_imported(name, 0, cctx) != NULL)
|| lookup_script(*arg, len) == OK) res = compile_load_scriptvar(cctx, name, *arg, &end, FALSE);
res = compile_load_scriptvar(cctx, name, *arg, &end,
FALSE);
// When the name starts with an uppercase letter or "x:" it // When the name starts with an uppercase letter or "x:" it
// can be a user defined function. // can be a user defined function.
// TODO: this is just guessing
if (res == FAIL && (ASCII_ISUPPER(*name) || name[1] == ':')) if (res == FAIL && (ASCII_ISUPPER(*name) || name[1] == ':'))
res = generate_funcref(cctx, name); res = generate_funcref(cctx, name);
} }
@@ -4697,8 +4701,8 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
int script_namespace = varlen > 1 int script_namespace = varlen > 1
&& STRNCMP(var_start, "s:", 2) == 0; && STRNCMP(var_start, "s:", 2) == 0;
int script_var = (script_namespace int script_var = (script_namespace
? lookup_script(var_start + 2, varlen - 2) ? lookup_script(var_start + 2, varlen - 2, FALSE)
: lookup_script(var_start, varlen)) == OK; : lookup_script(var_start, varlen, TRUE)) == OK;
imported_T *import = imported_T *import =
find_imported(var_start, varlen, cctx); find_imported(var_start, varlen, cctx);
@@ -6637,7 +6641,7 @@ compile_def_function(ufunc_T *ufunc, int set_return_type, cctx_T *outer_cctx)
|| lookup_local(ea.cmd, len, &cctx) != NULL || lookup_local(ea.cmd, len, &cctx) != NULL
|| lookup_arg(ea.cmd, len, NULL, NULL, || lookup_arg(ea.cmd, len, NULL, NULL,
NULL, &cctx) == OK NULL, &cctx) == OK
|| lookup_script(ea.cmd, len) == OK || lookup_script(ea.cmd, len, FALSE) == OK
|| find_imported(ea.cmd, len, &cctx) != NULL) || find_imported(ea.cmd, len, &cctx) != NULL)
{ {
line = compile_assignment(ea.cmd, &ea, CMD_SIZE, &cctx); line = compile_assignment(ea.cmd, &ea, CMD_SIZE, &cctx);