patch 8.2.4447: Vim9: can still use s:var in a compiled function

Problem:    Vim9: can still use s:var in a compiled function.
Solution:   Disallow using s:var for Vim9 script. (closes #9824)
This commit is contained in:
Bram Moolenaar
2022-02-22 20:43:36 +00:00
parent fe73255c92
commit afa048f0d4
5 changed files with 68 additions and 8 deletions

View File

@ -1,4 +1,4 @@
*vim9.txt* For Vim version 8.2. Last change: 2022 Feb 18
*vim9.txt* For Vim version 8.2. Last change: 2022 Feb 22
VIM REFERENCE MANUAL by Bram Moolenaar
@ -245,9 +245,11 @@ that the name interferes with builtin functions.
*vim9-s-namespace*
The use of the "s:" prefix is not supported at the Vim9 script level. All
functions and variables without a prefix are script-local.
In :def functions the use of "s:" is optional. This is because in legacy
script the "s:" might be needed. Disallowing the use of "s:" only in a :def
function in Vim9 script would be a bit confusing.
In :def functions the use of "s:" depends on the script: Script-local
variables and functions in a legacy script do use "s:", while in a Vim9 script
they do not use "s:". This matches what you see in the rest of the file.
In legacy functions the use of "s:" for script items is required, as before.
In all cases the function must be defined before used. That is when it is
@ -1467,7 +1469,7 @@ strings: >
# typename(mylist) == "list<string>", no error
There is a subtle difference between using a list constant directly and
through a variable declaraiton. Because of type inference, when using a list
through a variable declaration. Because of type inference, when using a list
constant to initialize a variable, this also sets the declared type: >
var mylist = [1, 2, 3]
# typename(mylist) == "list<number>"

View File

@ -220,7 +220,7 @@ def Test_assignment()
enddef
defcompile
END
v9.CheckScriptFailure(lines, 'E1089:')
v9.CheckScriptFailure(lines, 'E1268:')
g:inc_counter += 1
assert_equal(2, g:inc_counter)
@ -2460,6 +2460,49 @@ def Run_Test_declare_command_line()
g:StopVimInTerminal(buf)
enddef
def Test_using_s_var_in_function()
var lines =<< trim END
vim9script
var scriptlevel = 123
def SomeFunc()
echo s:scriptlevel
enddef
SomeFunc()
END
v9.CheckScriptFailure(lines, 'E1268:')
# OK in legacy script
lines =<< trim END
let s:scriptlevel = 123
def s:SomeFunc()
echo s:scriptlevel
enddef
call s:SomeFunc()
END
v9.CheckScriptSuccess(lines)
lines =<< trim END
vim9script
var scriptlevel = 123
def SomeFunc()
s:scriptlevel = 456
enddef
SomeFunc()
END
v9.CheckScriptFailure(lines, 'E1268:')
# OK in legacy script
lines =<< trim END
let s:scriptlevel = 123
def s:SomeFunc()
s:scriptlevel = 456
enddef
call s:SomeFunc()
call assert_equal(456, s:scriptlevel)
END
v9.CheckScriptSuccess(lines)
enddef
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker

View File

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

View File

@ -1331,6 +1331,12 @@ compile_lhs(
char_u *rawname = lhs->lhs_name
+ (lhs->lhs_name[1] == ':' ? 2 : 0);
if (script_namespace && current_script_is_vim9())
{
semsg(_(e_cannot_use_s_colon_in_vim9_script_str),
var_start);
return FAIL;
}
if (is_decl)
{
if (script_namespace)

View File

@ -422,8 +422,15 @@ compile_load(
{
case 'v': res = generate_LOADV(cctx, name, error);
break;
case 's': if (is_expr && ASCII_ISUPPER(*name)
&& find_func(name, FALSE) != NULL)
case 's': if (current_script_is_vim9())
{
semsg(_(e_cannot_use_s_colon_in_vim9_script_str),
*arg);
vim_free(name);
return FAIL;
}
if (is_expr && ASCII_ISUPPER(*name)
&& find_func(name, FALSE) != NULL)
res = generate_funcref(cctx, name, FALSE);
else
res = compile_load_scriptvar(cctx, name,