mirror of
https://github.com/vim/vim.git
synced 2025-09-25 03:54:15 -04:00
patch 8.2.2194: Vim9: cannot use :const or :final at the script level
Problem: Vim9: cannot use :const or :final at the script level. Solution: Support using :const and :final. (closes #7526)
This commit is contained in:
@@ -738,7 +738,7 @@ ex_let(exarg_T *eap)
|
|||||||
int first = TRUE;
|
int first = TRUE;
|
||||||
int concat;
|
int concat;
|
||||||
int has_assign;
|
int has_assign;
|
||||||
int flags = eap->cmdidx == CMD_const ? ASSIGN_CONST : 0;
|
int flags = 0;
|
||||||
int vim9script = in_vim9script();
|
int vim9script = in_vim9script();
|
||||||
|
|
||||||
if (eap->cmdidx == CMD_final && !vim9script)
|
if (eap->cmdidx == CMD_final && !vim9script)
|
||||||
@@ -756,7 +756,12 @@ ex_let(exarg_T *eap)
|
|||||||
// In legacy Vim script ":const" works like ":final".
|
// In legacy Vim script ":const" works like ":final".
|
||||||
eap->cmdidx = CMD_final;
|
eap->cmdidx = CMD_final;
|
||||||
|
|
||||||
// detect Vim9 assignment without ":let" or ":const"
|
if (eap->cmdidx == CMD_const)
|
||||||
|
flags |= ASSIGN_CONST;
|
||||||
|
else if (eap->cmdidx == CMD_final)
|
||||||
|
flags |= ASSIGN_FINAL;
|
||||||
|
|
||||||
|
// Vim9 assignment without ":let", ":const" or ":final"
|
||||||
if (eap->arg == eap->cmd)
|
if (eap->arg == eap->cmd)
|
||||||
flags |= ASSIGN_NO_DECL;
|
flags |= ASSIGN_NO_DECL;
|
||||||
|
|
||||||
@@ -909,7 +914,7 @@ ex_let_vars(
|
|||||||
int copy, // copy values from "tv", don't move
|
int copy, // copy values from "tv", don't move
|
||||||
int semicolon, // from skip_var_list()
|
int semicolon, // from skip_var_list()
|
||||||
int var_count, // from skip_var_list()
|
int var_count, // from skip_var_list()
|
||||||
int flags, // ASSIGN_CONST, ASSIGN_NO_DECL
|
int flags, // ASSIGN_FINAL, ASSIGN_CONST, ASSIGN_NO_DECL
|
||||||
char_u *op)
|
char_u *op)
|
||||||
{
|
{
|
||||||
char_u *arg = arg_start;
|
char_u *arg = arg_start;
|
||||||
@@ -1264,7 +1269,7 @@ ex_let_one(
|
|||||||
char_u *arg, // points to variable name
|
char_u *arg, // points to variable name
|
||||||
typval_T *tv, // value to assign to variable
|
typval_T *tv, // value to assign to variable
|
||||||
int copy, // copy value from "tv"
|
int copy, // copy value from "tv"
|
||||||
int flags, // ASSIGN_CONST, ASSIGN_NO_DECL
|
int flags, // ASSIGN_CONST, ASSIGN_FINAL, ASSIGN_NO_DECL
|
||||||
char_u *endchars, // valid chars after variable name or NULL
|
char_u *endchars, // valid chars after variable name or NULL
|
||||||
char_u *op) // "+", "-", "." or NULL
|
char_u *op) // "+", "-", "." or NULL
|
||||||
{
|
{
|
||||||
@@ -1277,6 +1282,7 @@ ex_let_one(
|
|||||||
char_u *tofree = NULL;
|
char_u *tofree = NULL;
|
||||||
|
|
||||||
if (in_vim9script() && (flags & ASSIGN_NO_DECL) == 0
|
if (in_vim9script() && (flags & ASSIGN_NO_DECL) == 0
|
||||||
|
&& (flags & (ASSIGN_CONST | ASSIGN_FINAL)) == 0
|
||||||
&& vim_strchr((char_u *)"$@&", *arg) != NULL)
|
&& vim_strchr((char_u *)"$@&", *arg) != NULL)
|
||||||
{
|
{
|
||||||
vim9_declare_error(arg);
|
vim9_declare_error(arg);
|
||||||
@@ -1286,7 +1292,7 @@ ex_let_one(
|
|||||||
// ":let $VAR = expr": Set environment variable.
|
// ":let $VAR = expr": Set environment variable.
|
||||||
if (*arg == '$')
|
if (*arg == '$')
|
||||||
{
|
{
|
||||||
if (flags & ASSIGN_CONST)
|
if (flags & (ASSIGN_CONST | ASSIGN_FINAL))
|
||||||
{
|
{
|
||||||
emsg(_("E996: Cannot lock an environment variable"));
|
emsg(_("E996: Cannot lock an environment variable"));
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -1338,7 +1344,7 @@ ex_let_one(
|
|||||||
// ":let &g:option = expr": Set global option value.
|
// ":let &g:option = expr": Set global option value.
|
||||||
else if (*arg == '&')
|
else if (*arg == '&')
|
||||||
{
|
{
|
||||||
if (flags & ASSIGN_CONST)
|
if (flags & (ASSIGN_CONST | ASSIGN_FINAL))
|
||||||
{
|
{
|
||||||
emsg(_(e_const_option));
|
emsg(_(e_const_option));
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -1422,7 +1428,7 @@ ex_let_one(
|
|||||||
// ":let @r = expr": Set register contents.
|
// ":let @r = expr": Set register contents.
|
||||||
else if (*arg == '@')
|
else if (*arg == '@')
|
||||||
{
|
{
|
||||||
if (flags & ASSIGN_CONST)
|
if (flags & (ASSIGN_CONST | ASSIGN_FINAL))
|
||||||
{
|
{
|
||||||
emsg(_("E996: Cannot lock a register"));
|
emsg(_("E996: Cannot lock a register"));
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -3056,7 +3062,7 @@ set_var_const(
|
|||||||
type_T *type,
|
type_T *type,
|
||||||
typval_T *tv_arg,
|
typval_T *tv_arg,
|
||||||
int copy, // make copy of value in "tv"
|
int copy, // make copy of value in "tv"
|
||||||
int flags) // ASSIGN_CONST, ASSIGN_NO_DECL
|
int flags) // ASSIGN_CONST, ASSIGN_FINAL, ASSIGN_NO_DECL
|
||||||
{
|
{
|
||||||
typval_T *tv = tv_arg;
|
typval_T *tv = tv_arg;
|
||||||
typval_T bool_tv;
|
typval_T bool_tv;
|
||||||
@@ -3077,6 +3083,7 @@ set_var_const(
|
|||||||
if (vim9script
|
if (vim9script
|
||||||
&& !is_script_local
|
&& !is_script_local
|
||||||
&& (flags & ASSIGN_NO_DECL) == 0
|
&& (flags & ASSIGN_NO_DECL) == 0
|
||||||
|
&& (flags & (ASSIGN_CONST | ASSIGN_FINAL)) == 0
|
||||||
&& name[1] == ':')
|
&& name[1] == ':')
|
||||||
{
|
{
|
||||||
vim9_declare_error(name);
|
vim9_declare_error(name);
|
||||||
@@ -3106,7 +3113,7 @@ set_var_const(
|
|||||||
{
|
{
|
||||||
if ((di->di_flags & DI_FLAGS_RELOAD) == 0)
|
if ((di->di_flags & DI_FLAGS_RELOAD) == 0)
|
||||||
{
|
{
|
||||||
if (flags & ASSIGN_CONST)
|
if (flags & (ASSIGN_CONST | ASSIGN_FINAL))
|
||||||
{
|
{
|
||||||
emsg(_(e_cannot_mod));
|
emsg(_(e_cannot_mod));
|
||||||
goto failed;
|
goto failed;
|
||||||
@@ -3206,7 +3213,7 @@ set_var_const(
|
|||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
di->di_flags = DI_FLAGS_ALLOC;
|
di->di_flags = DI_FLAGS_ALLOC;
|
||||||
if (flags & ASSIGN_CONST)
|
if (flags & (ASSIGN_CONST | ASSIGN_FINAL))
|
||||||
di->di_flags |= DI_FLAGS_LOCK;
|
di->di_flags |= DI_FLAGS_LOCK;
|
||||||
|
|
||||||
// A Vim9 script-local variable is also added to sn_all_vars and
|
// A Vim9 script-local variable is also added to sn_all_vars and
|
||||||
|
@@ -1127,6 +1127,30 @@ def Test_var_declaration()
|
|||||||
|
|
||||||
const FOO: number = 123
|
const FOO: number = 123
|
||||||
assert_equal(123, FOO)
|
assert_equal(123, FOO)
|
||||||
|
const FOOS = 'foos'
|
||||||
|
assert_equal('foos', FOOS)
|
||||||
|
final FLIST = [1]
|
||||||
|
assert_equal([1], FLIST)
|
||||||
|
FLIST[0] = 11
|
||||||
|
assert_equal([11], FLIST)
|
||||||
|
|
||||||
|
const g:FOO: number = 321
|
||||||
|
assert_equal(321, g:FOO)
|
||||||
|
const g:FOOS = 'gfoos'
|
||||||
|
assert_equal('gfoos', g:FOOS)
|
||||||
|
final g:FLIST = [2]
|
||||||
|
assert_equal([2], g:FLIST)
|
||||||
|
g:FLIST[0] = 22
|
||||||
|
assert_equal([22], g:FLIST)
|
||||||
|
|
||||||
|
const w:FOO: number = 46
|
||||||
|
assert_equal(46, w:FOO)
|
||||||
|
const w:FOOS = 'wfoos'
|
||||||
|
assert_equal('wfoos', w:FOOS)
|
||||||
|
final w:FLIST = [3]
|
||||||
|
assert_equal([3], w:FLIST)
|
||||||
|
w:FLIST[0] = 33
|
||||||
|
assert_equal([33], w:FLIST)
|
||||||
|
|
||||||
var s:other: number
|
var s:other: number
|
||||||
other = 1234
|
other = 1234
|
||||||
@@ -1150,6 +1174,12 @@ def Test_var_declaration()
|
|||||||
unlet g:var_test
|
unlet g:var_test
|
||||||
unlet g:var_prefixed
|
unlet g:var_prefixed
|
||||||
unlet g:other_var
|
unlet g:other_var
|
||||||
|
unlet g:FOO
|
||||||
|
unlet g:FOOS
|
||||||
|
unlet g:FLIST
|
||||||
|
unlet w:FOO
|
||||||
|
unlet w:FOOS
|
||||||
|
unlet w:FLIST
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
def Test_var_declaration_fails()
|
def Test_var_declaration_fails()
|
||||||
@@ -1159,6 +1189,22 @@ def Test_var_declaration_fails()
|
|||||||
END
|
END
|
||||||
CheckScriptFailure(lines, 'E1125:')
|
CheckScriptFailure(lines, 'E1125:')
|
||||||
|
|
||||||
|
lines =<< trim END
|
||||||
|
vim9script
|
||||||
|
const g:constvar = 'string'
|
||||||
|
g:constvar = 'xx'
|
||||||
|
END
|
||||||
|
CheckScriptFailure(lines, 'E741:')
|
||||||
|
unlet g:constvar
|
||||||
|
|
||||||
|
lines =<< trim END
|
||||||
|
vim9script
|
||||||
|
final w:finalvar = [9]
|
||||||
|
w:finalvar = [8]
|
||||||
|
END
|
||||||
|
CheckScriptFailure(lines, 'E1122:')
|
||||||
|
unlet w:finalvar
|
||||||
|
|
||||||
lines =<< trim END
|
lines =<< trim END
|
||||||
vim9script
|
vim9script
|
||||||
const var: string
|
const var: string
|
||||||
|
@@ -1032,7 +1032,7 @@ def Test_vim9script_call_fail_const()
|
|||||||
call Change()
|
call Change()
|
||||||
unlet g:Aconst
|
unlet g:Aconst
|
||||||
END
|
END
|
||||||
CheckScriptFailure(lines, 'E741: Value is locked: Aconst', 2)
|
CheckScriptFailure(lines, 'E1122: Variable is locked: Aconst', 2)
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
" Test that inside :function a Python function can be defined, :def is not
|
" Test that inside :function a Python function can be defined, :def is not
|
||||||
|
@@ -750,6 +750,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 */
|
||||||
|
/**/
|
||||||
|
2194,
|
||||||
/**/
|
/**/
|
||||||
2193,
|
2193,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -2144,7 +2144,7 @@ typedef enum {
|
|||||||
// Flags for assignment functions.
|
// Flags for assignment functions.
|
||||||
#define ASSIGN_FINAL 1 // ":final"
|
#define ASSIGN_FINAL 1 // ":final"
|
||||||
#define ASSIGN_CONST 2 // ":const"
|
#define ASSIGN_CONST 2 // ":const"
|
||||||
#define ASSIGN_NO_DECL 4 // "name = expr" without ":let" or ":const"
|
#define ASSIGN_NO_DECL 4 // "name = expr" without ":let"/":const"/":final"
|
||||||
|
|
||||||
#include "ex_cmds.h" // Ex command defines
|
#include "ex_cmds.h" // Ex command defines
|
||||||
#include "spell.h" // spell checking stuff
|
#include "spell.h" // spell checking stuff
|
||||||
|
Reference in New Issue
Block a user