# HG changeset patch # User Bram Moolenaar # Date 1598116504 -7200 # Node ID e420f3cf60e29b8952257b954737bde36932d2bb # Parent b7cac8d181c3a8d5a8ba52dd0d7d6dfaab1236ec patch 8.2.1510: using "var" in :def function may refer to legacy script var Commit: https://github.com/vim/vim/commit/5390099a9733f7952a612670693dd4ebf9e0e178 Author: Bram Moolenaar Date: Sat Aug 22 19:02:02 2020 +0200 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) diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim --- a/src/testdir/test_vim9_func.vim +++ b/src/testdir/test_vim9_func.vim @@ -829,30 +829,30 @@ endfunc let s:funcResult = 0 def FuncNoArgNoRet() - funcResult = 11 + s:funcResult = 11 enddef def FuncNoArgRetNumber(): number - funcResult = 22 + s:funcResult = 22 return 1234 enddef def FuncNoArgRetString(): string - funcResult = 45 + s:funcResult = 45 return 'text' enddef def FuncOneArgNoRet(arg: number) - funcResult = arg + s:funcResult = arg enddef def FuncOneArgRetNumber(arg: number): number - funcResult = arg + s:funcResult = arg return arg enddef def FuncTwoArgNoRet(one: bool, two: number) - funcResult = two + s:funcResult = two enddef def FuncOneArgRetString(arg: string): string @@ -865,31 +865,31 @@ enddef def Test_func_type() let Ref1: func() - funcResult = 0 + s:funcResult = 0 Ref1 = FuncNoArgNoRet Ref1() - assert_equal(11, funcResult) + assert_equal(11, s:funcResult) let Ref2: func - funcResult = 0 + s:funcResult = 0 Ref2 = FuncNoArgNoRet Ref2() - assert_equal(11, funcResult) + assert_equal(11, s:funcResult) - funcResult = 0 + s:funcResult = 0 Ref2 = FuncOneArgNoRet Ref2(12) - assert_equal(12, funcResult) + assert_equal(12, s:funcResult) - funcResult = 0 + s:funcResult = 0 Ref2 = FuncNoArgRetNumber assert_equal(1234, Ref2()) - assert_equal(22, funcResult) + assert_equal(22, s:funcResult) - funcResult = 0 + s:funcResult = 0 Ref2 = FuncOneArgRetNumber assert_equal(13, Ref2(13)) - assert_equal(13, funcResult) + assert_equal(13, s:funcResult) enddef def Test_repeat_return_type() diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -755,6 +755,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1510, +/**/ 1509, /**/ 1508, diff --git a/src/vim9compile.c b/src/vim9compile.c --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -260,15 +260,20 @@ lookup_arg( /* * 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. */ static int -lookup_script(char_u *name, size_t len) +lookup_script(char_u *name, size_t len, int vim9script) { int cc; hashtab_T *ht = &SCRIPT_VARS(current_sctx.sc_sid); dictitem_T *di; + if (vim9script && SCRIPT_ITEM(current_sctx.sc_sid)->sn_version + != SCRIPT_VERSION_VIM9) + return FAIL; cc = name[len]; name[len] = NUL; di = find_var_in_ht(ht, 0, name, TRUE); @@ -287,7 +292,7 @@ check_defined(char_u *p, size_t len, cct int c = p[len]; p[len] = NUL; - if (lookup_script(p, len) == OK + if (lookup_script(p, len, FALSE) == OK || (cctx != NULL && (lookup_local(p, len, cctx) != NULL || lookup_arg(p, len, NULL, NULL, NULL, cctx) == OK)) @@ -2145,15 +2150,14 @@ compile_load(char_u **arg, char_u *end_a else { // "var" can be script-local even without using "s:" if it - // already exists. - if (SCRIPT_ITEM(current_sctx.sc_sid)->sn_version - == SCRIPT_VERSION_VIM9 - || lookup_script(*arg, len) == OK) - res = compile_load_scriptvar(cctx, name, *arg, &end, - FALSE); + // already exists in a Vim9 script or when it's imported. + if (lookup_script(*arg, len, TRUE) == OK + || find_imported(name, 0, cctx) != NULL) + res = compile_load_scriptvar(cctx, name, *arg, &end, FALSE); // When the name starts with an uppercase letter or "x:" it // can be a user defined function. + // TODO: this is just guessing if (res == FAIL && (ASCII_ISUPPER(*name) || name[1] == ':')) res = generate_funcref(cctx, name); } @@ -4697,8 +4701,8 @@ compile_assignment(char_u *arg, exarg_T int script_namespace = varlen > 1 && STRNCMP(var_start, "s:", 2) == 0; int script_var = (script_namespace - ? lookup_script(var_start + 2, varlen - 2) - : lookup_script(var_start, varlen)) == OK; + ? lookup_script(var_start + 2, varlen - 2, FALSE) + : lookup_script(var_start, varlen, TRUE)) == OK; imported_T *import = find_imported(var_start, varlen, cctx); @@ -6637,7 +6641,7 @@ compile_def_function(ufunc_T *ufunc, int || lookup_local(ea.cmd, len, &cctx) != NULL || lookup_arg(ea.cmd, len, NULL, NULL, NULL, &cctx) == OK - || lookup_script(ea.cmd, len) == OK + || lookup_script(ea.cmd, len, FALSE) == OK || find_imported(ea.cmd, len, &cctx) != NULL) { line = compile_assignment(ea.cmd, &ea, CMD_SIZE, &cctx);