diff options
author | Bram Moolenaar <Bram@vim.org> | 2020-09-26 15:09:30 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2020-09-26 15:09:30 +0200 |
commit | 30fd8204cecb317d842b964d624d492088d6d15f (patch) | |
tree | 0df8a56d4a3c20098586020bc35b5e6e0b681894 /src | |
parent | 273af497cac345897cf6369baa87a070876a5815 (diff) | |
download | vim-git-30fd8204cecb317d842b964d624d492088d6d15f.tar.gz |
patch 8.2.1744: Vim9: using ":const!" is weirdv8.2.1744
Problem: Vim9: using ":const!" is weird.
Solution: Use "var" - "final" - "const" like Dart. "let" still works for
now.
Diffstat (limited to 'src')
-rw-r--r-- | src/cmdexpand.c | 2 | ||||
-rw-r--r-- | src/errors.h | 4 | ||||
-rw-r--r-- | src/eval.c | 22 | ||||
-rw-r--r-- | src/evalvars.c | 70 | ||||
-rw-r--r-- | src/ex_cmdidxs.h | 46 | ||||
-rw-r--r-- | src/ex_cmds.h | 6 | ||||
-rw-r--r-- | src/ex_docmd.c | 10 | ||||
-rw-r--r-- | src/proto/evalvars.pro | 1 | ||||
-rw-r--r-- | src/testdir/test_vim9_assign.vim | 341 | ||||
-rw-r--r-- | src/testdir/test_vim9_script.vim | 34 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim.h | 6 | ||||
-rw-r--r-- | src/vim9compile.c | 30 | ||||
-rw-r--r-- | src/vim9execute.c | 2 | ||||
-rw-r--r-- | src/vim9script.c | 9 |
15 files changed, 328 insertions, 257 deletions
diff --git a/src/cmdexpand.c b/src/cmdexpand.c index e7cf81998..f3e19bc02 100644 --- a/src/cmdexpand.c +++ b/src/cmdexpand.c @@ -1513,8 +1513,10 @@ set_one_cmd_context( break; #endif #ifdef FEAT_EVAL + case CMD_final: case CMD_const: case CMD_let: + case CMD_var: case CMD_if: case CMD_elseif: case CMD_while: diff --git a/src/errors.h b/src/errors.h index 0246fa103..34c47ca5b 100644 --- a/src/errors.h +++ b/src/errors.h @@ -270,4 +270,8 @@ EXTERN char e_variable_is_locked_str[] INIT(= N_("E1122: Variable is locked: %s")); EXTERN char e_missing_comma_before_argument_str[] INIT(= N_("E1123: Missing comma before argument: %s")); +EXTERN char e_str_cannot_be_used_in_legacy_vim_script[] + INIT(= N_("E1124: \"%s\" cannot be used in legacy Vim script")); +EXTERN char e_final_requires_a_value[] + INIT(= N_("E1125: Final requires a value")); #endif diff --git a/src/eval.c b/src/eval.c index 6c37e70d0..c8c4f6e5f 100644 --- a/src/eval.c +++ b/src/eval.c @@ -1213,7 +1213,7 @@ set_var_lval( char_u *endp, typval_T *rettv, int copy, - int flags, // LET_IS_CONST, LET_FORCEIT, LET_NO_COMMAND + int flags, // ASSIGN_CONST, ASSIGN_NO_DECL char_u *op) { int cc; @@ -1281,7 +1281,7 @@ set_var_lval( { typval_T tv; - if (flags & LET_IS_CONST) + if (flags & ASSIGN_CONST) { emsg(_(e_cannot_mod)); *endp = cc; @@ -1319,7 +1319,7 @@ set_var_lval( listitem_T *ll_li = lp->ll_li; int ll_n1 = lp->ll_n1; - if (flags & LET_IS_CONST) + if (flags & ASSIGN_CONST) { emsg(_("E996: Cannot lock a range")); return; @@ -1378,7 +1378,7 @@ set_var_lval( /* * Assign to a List or Dictionary item. */ - if (flags & LET_IS_CONST) + if (flags & ASSIGN_CONST) { emsg(_("E996: Cannot lock a list or dict")); return; @@ -1688,7 +1688,7 @@ next_for_item(void *fi_void, char_u *arg) { forinfo_T *fi = (forinfo_T *)fi_void; int result; - int flag = in_vim9script() ? LET_NO_COMMAND : 0; + int flag = in_vim9script() ? ASSIGN_NO_DECL : 0; listitem_T *item; if (fi->fi_blob != NULL) @@ -1741,11 +1741,12 @@ set_context_for_expression( char_u *arg, cmdidx_T cmdidx) { - int got_eq = FALSE; + int has_expr = cmdidx != CMD_let && cmdidx != CMD_var; int c; char_u *p; - if (cmdidx == CMD_let || cmdidx == CMD_const) + if (cmdidx == CMD_let || cmdidx == CMD_var + || cmdidx == CMD_const || cmdidx == CMD_final) { xp->xp_context = EXPAND_USER_VARS; if (vim_strpbrk(arg, (char_u *)"\"'+-*/%.=!?~|&$([<>,#") == NULL) @@ -1774,8 +1775,7 @@ set_context_for_expression( if (c == '&') { ++xp->xp_pattern; - xp->xp_context = cmdidx != CMD_let || got_eq - ? EXPAND_EXPRESSION : EXPAND_NOTHING; + xp->xp_context = has_expr ? EXPAND_EXPRESSION : EXPAND_NOTHING; } else if (c != ' ') { @@ -1792,7 +1792,7 @@ set_context_for_expression( } else if (c == '=') { - got_eq = TRUE; + has_expr = TRUE; xp->xp_context = EXPAND_EXPRESSION; } else if (c == '#' @@ -1808,7 +1808,7 @@ set_context_for_expression( // Function name can start with "<SNR>" and contain '#'. break; } - else if (cmdidx != CMD_let || got_eq) + else if (has_expr) { if (c == '"') // string { diff --git a/src/evalvars.c b/src/evalvars.c index 5ceaca48a..087a0cbdb 100644 --- a/src/evalvars.c +++ b/src/evalvars.c @@ -669,6 +669,25 @@ heredoc_get(exarg_T *eap, char_u *cmd, int script_get) } /* + * Vim9 variable declaration: + * ":var name" + * ":var name: type" + * ":var name = expr" + * ":var name: type = expr" + * etc. + */ + void +ex_var(exarg_T *eap) +{ + if (!in_vim9script()) + { + semsg(_(e_str_cannot_be_used_in_legacy_vim_script), ":var"); + return; + } + ex_let(eap); +} + +/* * ":let" list all variable values * ":let var1 var2" list variable values * ":let var = expr" assignment command. @@ -683,6 +702,9 @@ heredoc_get(exarg_T *eap, char_u *cmd, int script_get) * ":let var =<< ..." heredoc * ":let var: string" Vim9 declaration * + * ":final var = expr" assignment command. + * ":final [var1, var2] = expr" unpack list. + * * ":const" list all variable values * ":const var1 var2" list variable values * ":const var = expr" assignment command. @@ -702,14 +724,22 @@ ex_let(exarg_T *eap) int first = TRUE; int concat; int has_assign; - int flags = eap->cmdidx == CMD_const ? LET_IS_CONST : 0; + int flags = eap->cmdidx == CMD_const ? ASSIGN_CONST : 0; int vim9script = in_vim9script(); + if (eap->cmdidx == CMD_final && !vim9script) + { + // In legacy Vim script ":final" is short for ":finally". + ex_finally(eap); + return; + } + if (eap->cmdidx == CMD_const && !vim9script && !eap->forceit) + // In legacy Vim script ":const" works like ":final". + eap->cmdidx = CMD_final; + // detect Vim9 assignment without ":let" or ":const" if (eap->arg == eap->cmd) - flags |= LET_NO_COMMAND; - if (eap->forceit) - flags |= LET_FORCEIT; + flags |= ASSIGN_NO_DECL; argend = skip_var_list(arg, TRUE, &var_count, &semicolon, FALSE); if (argend == NULL) @@ -787,7 +817,7 @@ ex_let(exarg_T *eap) op[1] = NUL; if (*expr != '=') { - if (vim9script && (flags & LET_NO_COMMAND) == 0) + if (vim9script && (flags & ASSIGN_NO_DECL) == 0) { // +=, /=, etc. require an existing variable semsg(_(e_cannot_use_operator_on_new_variable), eap->arg); @@ -860,7 +890,7 @@ ex_let_vars( int copy, // copy values from "tv", don't move int semicolon, // from skip_var_list() int var_count, // from skip_var_list() - int flags, // LET_IS_CONST, LET_FORCEIT, LET_NO_COMMAND + int flags, // ASSIGN_CONST, ASSIGN_NO_DECL char_u *op) { char_u *arg = arg_start; @@ -1215,7 +1245,7 @@ ex_let_one( char_u *arg, // points to variable name typval_T *tv, // value to assign to variable int copy, // copy value from "tv" - int flags, // LET_IS_CONST, LET_FORCEIT, LET_NO_COMMAND + int flags, // ASSIGN_CONST, ASSIGN_NO_DECL char_u *endchars, // valid chars after variable name or NULL char_u *op) // "+", "-", "." or NULL { @@ -1227,7 +1257,7 @@ ex_let_one( int opt_flags; char_u *tofree = NULL; - if (in_vim9script() && (flags & LET_NO_COMMAND) == 0 + if (in_vim9script() && (flags & ASSIGN_NO_DECL) == 0 && vim_strchr((char_u *)"$@&", *arg) != NULL) { vim9_declare_error(arg); @@ -1237,7 +1267,7 @@ ex_let_one( // ":let $VAR = expr": Set environment variable. if (*arg == '$') { - if (flags & LET_IS_CONST) + if (flags & ASSIGN_CONST) { emsg(_("E996: Cannot lock an environment variable")); return NULL; @@ -1289,7 +1319,7 @@ ex_let_one( // ":let &g:option = expr": Set global option value. else if (*arg == '&') { - if (flags & LET_IS_CONST) + if (flags & ASSIGN_CONST) { emsg(_(e_const_option)); return NULL; @@ -1373,7 +1403,7 @@ ex_let_one( // ":let @r = expr": Set register contents. else if (*arg == '@') { - if (flags & LET_IS_CONST) + if (flags & ASSIGN_CONST) { emsg(_("E996: Cannot lock a register")); return NULL; @@ -2926,7 +2956,7 @@ set_var( typval_T *tv, int copy) // make copy of value in "tv" { - set_var_const(name, NULL, tv, copy, LET_NO_COMMAND); + set_var_const(name, NULL, tv, copy, ASSIGN_NO_DECL); } /* @@ -2940,7 +2970,7 @@ set_var_const( type_T *type, typval_T *tv_arg, int copy, // make copy of value in "tv" - int flags) // LET_IS_CONST, LET_FORCEIT, LET_NO_COMMAND + int flags) // ASSIGN_CONST, ASSIGN_NO_DECL { typval_T *tv = tv_arg; typval_T bool_tv; @@ -2960,7 +2990,7 @@ set_var_const( if (vim9script && !is_script_local - && (flags & LET_NO_COMMAND) == 0 + && (flags & ASSIGN_NO_DECL) == 0 && name[1] == ':') { vim9_declare_error(name); @@ -2990,7 +3020,7 @@ set_var_const( { if ((di->di_flags & DI_FLAGS_RELOAD) == 0) { - if (flags & LET_IS_CONST) + if (flags & ASSIGN_CONST) { emsg(_(e_cannot_mod)); goto failed; @@ -2998,7 +3028,7 @@ set_var_const( if (is_script_local && vim9script) { - if ((flags & LET_NO_COMMAND) == 0) + if ((flags & ASSIGN_NO_DECL) == 0) { semsg(_(e_redefining_script_item_str), name); goto failed; @@ -3094,7 +3124,7 @@ set_var_const( goto failed; } di->di_flags = DI_FLAGS_ALLOC; - if (flags & LET_IS_CONST) + if (flags & ASSIGN_CONST) di->di_flags |= DI_FLAGS_LOCK; if (is_script_local && vim9script) @@ -3113,7 +3143,7 @@ set_var_const( sv->sv_type = typval2type(tv, &si->sn_type_list); else sv->sv_type = type; - sv->sv_const = (flags & LET_IS_CONST); + sv->sv_const = (flags & ASSIGN_CONST); sv->sv_export = is_export; ++si->sn_var_vals.ga_len; @@ -3132,8 +3162,8 @@ set_var_const( init_tv(tv); } - // ":const var = val" locks the value; in Vim9 script only with ":const!" - if ((flags & LET_IS_CONST) && (!vim9script || (flags & LET_FORCEIT))) + // ":const var = val" locks the value + if (flags & ASSIGN_CONST) // Like :lockvar! name: lock the value and what it contains, but only // if the reference count is up to one. That locks only literal // values. diff --git a/src/ex_cmdidxs.h b/src/ex_cmdidxs.h index 53081d069..0f9eb39ff 100644 --- a/src/ex_cmdidxs.h +++ b/src/ex_cmdidxs.h @@ -11,26 +11,26 @@ static const unsigned short cmdidxs1[26] = /* d */ 108, /* e */ 133, /* f */ 156, - /* g */ 172, - /* h */ 178, - /* i */ 187, - /* j */ 206, - /* k */ 208, - /* l */ 213, - /* m */ 275, - /* n */ 293, - /* o */ 313, - /* p */ 325, - /* q */ 364, - /* r */ 367, - /* s */ 387, - /* t */ 456, - /* u */ 501, - /* v */ 512, - /* w */ 531, - /* x */ 545, - /* y */ 555, - /* z */ 556 + /* g */ 173, + /* h */ 179, + /* i */ 188, + /* j */ 207, + /* k */ 209, + /* l */ 214, + /* m */ 276, + /* n */ 294, + /* o */ 314, + /* p */ 326, + /* q */ 365, + /* r */ 368, + /* s */ 388, + /* t */ 457, + /* u */ 502, + /* v */ 513, + /* w */ 533, + /* x */ 547, + /* y */ 557, + /* z */ 558 }; /* @@ -46,7 +46,7 @@ static const unsigned char cmdidxs2[26][26] = /* c */ { 3, 12, 16, 18, 20, 22, 25, 0, 0, 0, 0, 33, 37, 40, 46, 56, 58, 59, 60, 0, 62, 0, 65, 0, 0, 0 }, /* d */ { 0, 0, 0, 0, 0, 0, 0, 0, 8, 18, 0, 19, 0, 0, 20, 0, 0, 22, 23, 0, 0, 0, 0, 0, 0, 0 }, /* e */ { 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 10, 0, 0, 0, 0, 0, 0, 0, 17, 0, 18, 0, 0 }, - /* f */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0 }, + /* f */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0 }, /* g */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 4, 5, 0, 0, 0, 0 }, /* h */ { 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* i */ { 1, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 5, 6, 0, 0, 0, 0, 0, 14, 0, 16, 0, 0, 0, 0, 0 }, @@ -62,11 +62,11 @@ static const unsigned char cmdidxs2[26][26] = /* s */ { 2, 6, 15, 0, 19, 23, 0, 25, 26, 0, 0, 29, 31, 35, 39, 41, 0, 50, 0, 51, 0, 63, 64, 0, 65, 0 }, /* t */ { 2, 0, 19, 0, 24, 26, 0, 27, 0, 28, 0, 29, 33, 36, 38, 39, 0, 40, 42, 0, 43, 0, 0, 0, 0, 0 }, /* u */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* v */ { 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 10, 13, 0, 0, 0, 0, 16, 0, 17, 0, 0, 0, 0, 0 }, + /* v */ { 1, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 11, 14, 0, 0, 0, 0, 17, 0, 18, 0, 0, 0, 0, 0 }, /* w */ { 2, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 0, 0, 8, 0, 9, 10, 0, 0, 0, 12, 13, 0, 0, 0, 0 }, /* x */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 5, 0, 0, 0, 7, 0, 0, 8, 0, 0, 0, 0, 0 }, /* y */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* z */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; -static const int command_count = 569; +static const int command_count = 571; diff --git a/src/ex_cmds.h b/src/ex_cmds.h index 8ef9eb41d..0c83f521f 100644 --- a/src/ex_cmds.h +++ b/src/ex_cmds.h @@ -592,6 +592,9 @@ EXCMD(CMD_filter, "filter", ex_wrongmodifier, EXCMD(CMD_find, "find", ex_find, EX_RANGE|EX_BANG|EX_FILE1|EX_CMDARG|EX_ARGOPT|EX_TRLBAR|EX_NEEDARG, ADDR_OTHER), +EXCMD(CMD_final, "final", ex_let, + EX_EXTRA|EX_NOTRLCOM|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK, + ADDR_NONE), EXCMD(CMD_finally, "finally", ex_finally, EX_TRLBAR|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK, ADDR_NONE), @@ -1648,6 +1651,9 @@ EXCMD(CMD_update, "update", ex_update, EXCMD(CMD_vglobal, "vglobal", ex_global, EX_RANGE|EX_WHOLEFOLD|EX_EXTRA|EX_DFLALL|EX_CMDWIN|EX_LOCK_OK, ADDR_LINES), +EXCMD(CMD_var, "var", ex_var, + EX_EXTRA|EX_NOTRLCOM|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK, + ADDR_NONE), EXCMD(CMD_version, "version", ex_version, EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, ADDR_NONE), diff --git a/src/ex_docmd.c b/src/ex_docmd.c index 7f963887b..f58415327 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -2421,6 +2421,7 @@ do_one_cmd( case CMD_eval: case CMD_execute: case CMD_filter: + case CMD_final: case CMD_help: case CMD_hide: case CMD_ijump: @@ -2442,9 +2443,9 @@ do_one_cmd( case CMD_noswapfile: case CMD_perl: case CMD_psearch: - case CMD_python: case CMD_py3: case CMD_python3: + case CMD_python: case CMD_return: case CMD_rightbelow: case CMD_ruby: @@ -2460,6 +2461,7 @@ do_one_cmd( case CMD_topleft: case CMD_unlet: case CMD_unlockvar: + case CMD_var: case CMD_verbose: case CMD_vertical: case CMD_wincmd: @@ -3244,7 +3246,7 @@ find_ex_command( if (skip_expr(&after) == OK && (*after == '=' || (*after != NUL && after[1] == '='))) - eap->cmdidx = CMD_let; + eap->cmdidx = CMD_var; else eap->cmdidx = CMD_eval; --emsg_silent; @@ -3268,7 +3270,7 @@ find_ex_command( } if (p > eap->cmd && *skipwhite(p) == '=') { - eap->cmdidx = CMD_let; + eap->cmdidx = CMD_var; return eap->cmd; } } @@ -3287,7 +3289,7 @@ find_ex_command( || *eap->cmd == '@' || lookup(eap->cmd, p - eap->cmd, cctx) != NULL) { - eap->cmdidx = CMD_let; + eap->cmdidx = CMD_var; return eap->cmd; } } diff --git a/src/proto/evalvars.pro b/src/proto/evalvars.pro index 569a73ae2..69655089e 100644 --- a/src/proto/evalvars.pro +++ b/src/proto/evalvars.pro @@ -14,6 +14,7 @@ int get_spellword(list_T *list, char_u **pp); void prepare_vimvar(int idx, typval_T *save_tv); void restore_vimvar(int idx, typval_T *save_tv); list_T *heredoc_get(exarg_T *eap, char_u *cmd, int script_get); +void ex_var(exarg_T *eap); void ex_let(exarg_T *eap); int ex_let_vars(char_u *arg_start, typval_T *tv, int copy, int semicolon, int var_count, int flags, char_u *op); char_u *skip_var_list(char_u *arg, int include_type, int *var_count, int *semicolon, int silent); diff --git a/src/testdir/test_vim9_assign.vim b/src/testdir/test_vim9_assign.vim index 4c825e8f6..94861e549 100644 --- a/src/testdir/test_vim9_assign.vim +++ b/src/testdir/test_vim9_assign.vim @@ -12,30 +12,30 @@ let g:alist = [7] let g:astring = 'text' def Test_assignment_bool() - let bool1: bool = true + var bool1: bool = true assert_equal(v:true, bool1) - let bool2: bool = false + var bool2: bool = false assert_equal(v:false, bool2) - let bool3: bool = 0 + var bool3: bool = 0 assert_equal(false, bool3) - let bool4: bool = 1 + var bool4: bool = 1 assert_equal(true, bool4) - let bool5: bool = 'yes' && 'no' + var bool5: bool = 'yes' && 'no' assert_equal(true, bool5) - let bool6: bool = [] && 99 + var bool6: bool = [] && 99 assert_equal(false, bool6) - let bool7: bool = [] || #{a: 1} && 99 + var bool7: bool = [] || #{a: 1} && 99 assert_equal(true, bool7) - let lines =<< trim END + var lines =<< trim END vim9script def GetFlag(): bool - let flag: bool = 1 + var flag: bool = 1 return flag enddef - let flag: bool = GetFlag() + var flag: bool = GetFlag() assert_equal(true, flag) flag = 0 assert_equal(false, flag) @@ -47,41 +47,42 @@ def Test_assignment_bool() assert_equal(false, flag) END CheckScriptSuccess(lines) - CheckDefAndScriptFailure(['let x: bool = 2'], 'E1012:') - CheckDefAndScriptFailure(['let x: bool = -1'], 'E1012:') - CheckDefAndScriptFailure(['let x: bool = [1]'], 'E1012:') - CheckDefAndScriptFailure(['let x: bool = {}'], 'E1012:') - CheckDefAndScriptFailure(['let x: bool = "x"'], 'E1012:') + CheckDefAndScriptFailure(['var x: bool = 2'], 'E1012:') + CheckDefAndScriptFailure(['var x: bool = -1'], 'E1012:') + CheckDefAndScriptFailure(['var x: bool = [1]'], 'E1012:') + CheckDefAndScriptFailure(['var x: bool = {}'], 'E1012:') + CheckDefAndScriptFailure(['var x: bool = "x"'], 'E1012:') enddef def Test_syntax() - let var = 234 - let other: list<string> = ['asdf'] + var var = 234 + var other: list<string> = ['asdf'] enddef def Test_assignment() - CheckDefFailure(['let x:string'], 'E1069:') - CheckDefFailure(['let x:string = "x"'], 'E1069:') - CheckDefFailure(['let a:string = "x"'], 'E1069:') - CheckDefFailure(['let lambda = {-> "lambda"}'], 'E704:') + CheckDefFailure(['var x:string'], 'E1069:') + CheckDefFailure(['var x:string = "x"'], 'E1069:') + CheckDefFailure(['var a:string = "x"'], 'E1069:') + CheckDefFailure(['var lambda = {-> "lambda"}'], 'E704:') + CheckScriptFailure(['var x = "x"'], 'E1124:') - let nr: number = 1234 - CheckDefFailure(['let nr: number = "asdf"'], 'E1012:') + var nr: number = 1234 + CheckDefFailure(['var nr: number = "asdf"'], 'E1012:') - let a: number = 6 #comment + var a: number = 6 #comment assert_equal(6, a) if has('channel') - let chan1: channel - let job1: job - let job2: job = job_start('willfail') + var chan1: channel + var job1: job + var job2: job = job_start('willfail') endif if has('float') - let float1: float = 3.4 + var float1: float = 3.4 endif - let Funky1: func - let Funky2: func = function('len') - let Party2: func = funcref('g:Test_syntax') + var Funky1: func + var Funky2: func = function('len') + var Party2: func = funcref('g:Test_syntax') g:newvar = 'new' #comment assert_equal('new', g:newvar) @@ -97,7 +98,7 @@ def Test_assignment() assert_equal('foobar', $ENVVAR) $ENVVAR = '' - let lines =<< trim END + var lines =<< trim END vim9script $ENVVAR = 'barfoo' assert_equal('barfoo', $ENVVAR) @@ -126,15 +127,15 @@ def Test_assignment() assert_equal(2, &ts) if has('float') - let f100: float = 100.0 + var f100: float = 100.0 f100 /= 5 assert_equal(20.0, f100) - let f200: float = 200.0 + var f200: float = 200.0 f200 /= 5.0 assert_equal(40.0, f200) - CheckDefFailure(['let nr: number = 200', 'nr /= 5.0'], 'E1012:') + CheckDefFailure(['var nr: number = 200', 'nr /= 5.0'], 'E1012:') endif lines =<< trim END @@ -163,11 +164,11 @@ def Test_assignment() CheckDefFailure(['&path += 3'], 'E1012:') CheckDefExecFailure(['&bs = "asdf"'], 'E474:') # test freeing ISN_STOREOPT - CheckDefFailure(['&ts = 3', 'let asdf'], 'E1022:') + CheckDefFailure(['&ts = 3', 'var asdf'], 'E1022:') &ts = 8 lines =<< trim END - let save_TI = &t_TI + var save_TI = &t_TI &t_TI = '' assert_equal('', &t_TI) &t_TI = 'xxx' @@ -179,8 +180,8 @@ def Test_assignment() CheckDefFailure(['&t_TI = 123'], 'E1012:') CheckScriptFailure(['vim9script', '&t_TI = 123'], 'E928:') - CheckDefFailure(['let s:var = 123'], 'E1101:') - CheckDefFailure(['let s:var: number'], 'E1101:') + CheckDefFailure(['var s:var = 123'], 'E1101:') + CheckDefFailure(['var s:var: number'], 'E1101:') lines =<< trim END vim9script @@ -217,20 +218,20 @@ def Test_assignment() # this should not leak if 0 - let text =<< trim END + var text =<< trim END some text END endif enddef def Test_extend_list() - let lines =<< trim END + var lines =<< trim END vim9script - let l: list<number> + var l: list<number> l += [123] assert_equal([123], l) - let d: dict<number> + var d: dict<number> d['one'] = 1 assert_equal(#{one: 1}, d) END @@ -239,41 +240,41 @@ enddef def Test_single_letter_vars() # single letter variables - let a: number = 123 + var a: number = 123 a = 123 assert_equal(123, a) - let b: number + var b: number b = 123 assert_equal(123, b) - let g: number + var g: number g = 123 assert_equal(123, g) - let s: number + var s: number s = 123 assert_equal(123, s) - let t: number + var t: number t = 123 assert_equal(123, t) - let v: number + var v: number v = 123 assert_equal(123, v) - let w: number + var w: number w = 123 assert_equal(123, w) enddef def Test_vim9_single_char_vars() - let lines =<< trim END + var lines =<< trim END vim9script # single character variable declarations work - let a: string - let b: number - let l: list<any> - let s: string - let t: number - let v: number - let w: number + var a: string + var b: number + var l: list<any> + var s: string + var t: number + var v: number + var w: number # script-local variables can be used without s: prefix a = 'script-a' @@ -298,14 +299,14 @@ def Test_vim9_single_char_vars() enddef def Test_assignment_list() - let list1: list<bool> = [false, true, false] - let list2: list<number> = [1, 2, 3] - let list3: list<string> = ['sdf', 'asdf'] - let list4: list<any> = ['yes', true, 1234] - let list5: list<blob> = [0z01, 0z02] + var list1: list<bool> = [false, true, false] + var list2: list<number> = [1, 2, 3] + var list3: list<string> = ['sdf', 'asdf'] + var list4: list<any> = ['yes', true, 1234] + var list5: list<blob> = [0z01, 0z02] - let listS: list<string> = [] - let listN: list<number> = [] + var listS: list<string> = [] + var listN: list<number> = [] assert_equal([1, 2, 3], list2) list2[-1] = 99 @@ -320,19 +321,19 @@ def Test_assignment_list() list3 += ['end'] assert_equal(['sdf', 'asdf', 'end'], list3) - CheckDefExecFailure(['let ll = [1, 2, 3]', 'll[-4] = 6'], 'E684:') - CheckDefExecFailure(['let [v1, v2] = [1, 2]'], 'E1092:') + CheckDefExecFailure(['var ll = [1, 2, 3]', 'll[-4] = 6'], 'E684:') + CheckDefExecFailure(['var [v1, v2] = [1, 2]'], 'E1092:') # type becomes list<any> - let somelist = rand() > 0 ? [1, 2, 3] : ['a', 'b', 'c'] + var somelist = rand() > 0 ? [1, 2, 3] : ['a', 'b', 'c'] enddef def Test_assignment_list_vim9script() - let lines =<< trim END + var lines =<< trim END vim9script - let v1: number - let v2: number - let v3: number + var v1: number + var v2: number + var v3: number [v1, v2, v3] = [1, 2, 3] assert_equal([1, 2, 3], [v1, v2, v3]) END @@ -340,27 +341,27 @@ def Test_assignment_list_vim9script() enddef def Test_assignment_dict() - let dict1: dict<bool> = #{one: false, two: true} - let dict2: dict<number> = #{one: 1, two: 2} - let dict3: dict<string> = #{key: 'value'} - let dict4: dict<any> = #{one: 1, two: '2'} - let dict5: dict<blob> = #{one: 0z01, two: 0z02} + var dict1: dict<bool> = #{one: false, two: true} + var dict2: dict<number> = #{one: 1, two: 2} + var dict3: dict<string> = #{key: 'value'} + var dict4: dict<any> = #{one: 1, two: '2'} + var dict5: dict<blob> = #{one: 0z01, two: 0z02} # overwrite dict3['key'] = 'another' # empty key can be used - let dd = {} + var dd = {} dd[""] = 6 assert_equal({'': 6}, dd) # type becomes dict<any> - let somedict = rand() > 0 ? #{a: 1, b: 2} : #{a: 'a', b: 'b'} + var somedict = rand() > 0 ? #{a: 1, b: 2} : #{a: 'a', b: 'b'} # assignment to script-local dict - let lines =<< trim END + var lines =<< trim END vim9script - let test: dict<any> = {} + var test: dict<any> = {} def FillDict(): dict<any> test['a'] = 43 return test @@ -371,7 +372,7 @@ def Test_assignment_dict() lines =<< trim END vim9script - let test: dict<any> + var test: dict<any> def FillDict(): dict<any> test['a'] = 43 return test @@ -408,7 +409,7 @@ enddef def Test_assignment_local() # Test in a separated file in order not to the current buffer/window/tab is # changed. - let script_lines: list<string> =<< trim END + var script_lines: list<string> =<< trim END let b:existing = 'yes' let w:existing = 'yes' let t:existing = 'yes' @@ -446,37 +447,37 @@ enddef def Test_assignment_default() # Test default values. - let thebool: bool + var thebool: bool assert_equal(v:false, thebool) - let thenumber: number + var thenumber: number assert_equal(0, thenumber) if has('float') - let thefloat: float + var thefloat: float assert_equal(0.0, thefloat) endif - let thestring: string + var thestring: string assert_equal('', thestring) - let theblob: blob + var theblob: blob assert_equal(0z, theblob) - let Thefunc: func + var Thefunc: func assert_equal(test_null_function(), Thefunc) - let thelist: list<any> + var thelist: list<any> assert_equal([], thelist) - let thedict: dict<any> + var thedict: dict<any> assert_equal({}, thedict) if has('channel') - let thejob: job + var thejob: job assert_equal(test_null_job(), thejob) - let thechannel: channel + var thechannel: channel assert_equal(test_null_channel(), thechannel) if has('unix') && executable('cat') @@ -487,14 +488,14 @@ def Test_assignment_default() endif endif - let nr = 1234 | nr = 5678 + var nr = 1234 | nr = 5678 assert_equal(5678, nr) enddef def Test_assignment_var_list() - let v1: string - let v2: string - let vrem: list<string> + var v1: string + var v2: string + var vrem: list<string> [v1] = ['aaa'] assert_equal('aaa', v1) @@ -519,18 +520,18 @@ def Test_assignment_var_list() enddef def Test_assignment_vim9script() - let lines =<< trim END + var lines =<< trim END vim9script def Func(): list<number> return [1, 2] enddef - let var1: number - let var2: number + var var1: number + var var2: number [var1, var2] = Func() assert_equal(1, var1) assert_equal(2, var2) - let ll = + var ll = Func() assert_equal([1, 2], ll) @@ -551,15 +552,15 @@ def Test_assignment_vim9script() assert_equal('plus', @+) endif - let a: number = 123 + var a: number = 123 assert_equal(123, a) - let s: string = 'yes' + var s: string = 'yes' assert_equal('yes', s) - let b: number = 42 + var b: number = 42 assert_equal(42, b) - let w: number = 43 + var w: number = 43 assert_equal(43, w) - let t: number = 44 + var t: number = 44 assert_equal(44, t) END CheckScriptSuccess(lines) @@ -571,80 +572,80 @@ def Mess(): string enddef def Test_assignment_failure() - CheckDefFailure(['let var=234'], 'E1004:') - CheckDefFailure(['let var =234'], 'E1004:') - CheckDefFailure(['let var= 234'], 'E1004:') - - CheckScriptFailure(['vim9script', 'let var=234'], 'E1004:') - CheckScriptFailure(['vim9script', 'let var=234'], "before and after '='") - CheckScriptFailure(['vim9script', 'let var =234'], 'E1004:') - CheckScriptFailure(['vim9script', 'let var= 234'], 'E1004:') - CheckScriptFailure(['vim9script', 'let var = 234', 'var+=234'], 'E1004:') - CheckScriptFailure(['vim9script', 'let var = 234', 'var+=234'], "before and after '+='") - CheckScriptFailure(['vim9script', 'let var = "x"', 'var..="y"'], 'E1004:') - CheckScriptFailure(['vim9script', 'let var = "x"', 'var..="y"'], "before and after '..='") - - CheckDefFailure(['let true = 1'], 'E1034:') - CheckDefFailure(['let false = 1'], 'E1034:') + CheckDefFailure(['var var=234'], 'E1004:') + CheckDefFailure(['var var =234'], 'E1004:') + CheckDefFailure(['var var= 234'], 'E1004:') + + CheckScriptFailure(['vim9script', 'var var=234'], 'E1004:') + CheckScriptFailure(['vim9script', 'var var=234'], "before and after '='") + CheckScriptFailure(['vim9script', 'var var =234'], 'E1004:') + CheckScriptFailure(['vim9script', 'var var= 234'], 'E1004:') + CheckScriptFailure(['vim9script', 'var var = 234', 'var+=234'], 'E1004:') + CheckScriptFailure(['vim9script', 'var var = 234', 'var+=234'], "before and after '+='") + CheckScriptFailure(['vim9script', 'var var = "x"', 'var..="y"'], 'E1004:') + CheckScriptFailure(['vim9script', 'var var = "x"', 'var..="y"'], "before and after '..='") + + CheckDefFailure(['var true = 1'], 'E1034:') + CheckDefFailure(['var false = 1'], 'E1034:') CheckDefFailure(['[a; b; c] = g:list'], 'E452:') - CheckDefExecFailure(['let a: number', + CheckDefExecFailure(['var a: number', '[a] = test_null_list()'], 'E1093:') - CheckDefExecFailure(['let a: number', + CheckDefExecFailure(['var a: number', '[a] = []'], 'E1093:') - CheckDefExecFailure(['let x: number', - 'let y: number', + CheckDefExecFailure(['var x: number', + 'var y: number', '[x, y] = [1]'], 'E1093:') - CheckDefExecFailure(['let x: number', - 'let y: number', - 'let z: list<number>', + CheckDefExecFailure(['var x: number', + 'var y: number', + 'var z: list<number>', '[x, y; z] = [1]'], 'E1093:') - CheckDefFailure(['let somevar'], "E1022:") - CheckDefFailure(['let &tabstop = 4'], 'E1052:') + CheckDefFailure(['var somevar'], "E1022:") + CheckDefFailure(['var &tabstop = 4'], 'E1052:') CheckDefFailure(['&g:option = 5'], 'E113:') - CheckScriptFailure(['vim9script', 'let &tabstop = 4'], 'E1052:') + CheckScriptFailure(['vim9script', 'var &tabstop = 4'], 'E1052:') - CheckDefFailure(['let $VAR = 5'], 'E1016: Cannot declare an environment variable:') - CheckScriptFailure(['vim9script', 'let $ENV = "xxx"'], 'E1016:') + CheckDefFailure(['var $VAR = 5'], 'E1016: Cannot declare an environment variable:') + CheckScriptFailure(['vim9script', 'var $ENV = "xxx"'], 'E1016:') if has('dnd') - CheckDefFailure(['let @~ = 5'], 'E1066:') + CheckDefFailure(['var @~ = 5'], 'E1066:') else - CheckDefFailure(['let @~ = 5'], 'E354:') + CheckDefFailure(['var @~ = 5'], 'E354:') CheckDefFailure(['@~ = 5'], 'E354:') endif - CheckDefFailure(['let @a = 5'], 'E1066:') - CheckDefFailure(['let @/ = "x"'], 'E1066:') - CheckScriptFailure(['vim9script', 'let @a = "abc"'], 'E1066:') + CheckDefFailure(['var @a = 5'], 'E1066:') + CheckDefFailure(['var @/ = "x"'], 'E1066:') + CheckScriptFailure(['vim9script', 'var @a = "abc"'], 'E1066:') - CheckDefFailure(['let g:var = 5'], 'E1016: Cannot declare a global variable:') - CheckDefFailure(['let w:var = 5'], 'E1016: Cannot declare a window variable:') - CheckDefFailure(['let b:var = 5'], 'E1016: Cannot declare a buffer variable:') - CheckDefFailure(['let t:var = 5'], 'E1016: Cannot declare a tab variable:') + CheckDefFailure(['var g:var = 5'], 'E1016: Cannot declare a global variable:') + CheckDefFailure(['var w:var = 5'], 'E1016: Cannot declare a window variable:') + CheckDefFailure(['var b:var = 5'], 'E1016: Cannot declare a buffer variable:') + CheckDefFailure(['var t:var = 5'], 'E1016: Cannot declare a tab variable:') - CheckDefFailure(['let anr = 4', 'anr ..= "text"'], 'E1019:') - CheckDefFailure(['let xnr += 4'], 'E1020:', 1) - CheckScriptFailure(['vim9script', 'let xnr += 4'], 'E1020:') - CheckDefFailure(["let xnr = xnr + 1"], 'E1001:', 1) - CheckScriptFailure(['vim9script', 'let xnr = xnr + 4'], 'E121:') + CheckDefFailure(['var anr = 4', 'anr ..= "text"'], 'E1019:') + CheckDefFailure(['var xnr += 4'], 'E1020:', 1) + CheckScriptFailure(['vim9script', 'var xnr += 4'], 'E1020:') + CheckDefFailure(["var xnr = xnr + 1"], 'E1001:', 1) + CheckScriptFailure(['vim9script', 'var xnr = xnr + 4'], 'E121:') - CheckScriptFailure(['vim9script', 'def Func()', 'let dummy = s:notfound', 'enddef', 'defcompile'], 'E1108:') + CheckScriptFailure(['vim9script', 'def Func()', 'var dummy = s:notfound', 'enddef', 'defcompile'], 'E1108:') - CheckDefFailure(['let var: list<string> = [123]'], 'expected list<string> but got list<number>') - CheckDefFailure(['let var: list<number> = ["xx"]'], 'expected list<number> but got list<string>') + CheckDefFailure(['var var: list<string> = [123]'], 'expected list<string> but got list<number>') + CheckDefFailure(['var var: list<number> = ["xx"]'], 'expected list<number> but got list<string>') - CheckDefFailure(['let var: dict<string> = #{key: 123}'], 'expected dict<string> but got dict<number>') - CheckDefFailure(['let var: dict<number> = #{key: "xx"}'], 'expected dict<number> but got dict<string>') + CheckDefFailure(['var var: dict<string> = #{key: 123}'], 'expected dict<string> but got dict<number>') + CheckDefFailure(['var var: dict<number> = #{key: "xx"}'], 'expected dict<number> but got dict<string>') - CheckDefFailure(['let var = feedkeys("0")'], 'E1031:') - CheckDefFailure(['let var: number = feedkeys("0")'], 'expected number but got void') + CheckDefFailure(['var var = feedkeys("0")'], 'E1031:') + CheckDefFailure(['var var: number = feedkeys("0")'], 'expected number but got void') - CheckDefFailure(['let var: dict <number>'], 'E1068:') - CheckDefFailure(['let var: dict<number'], 'E1009:') + CheckDefFailure(['var var: dict <number>'], 'E1068:') + CheckDefFailure(['var var: dict<number'], 'E1009:') assert_fails('s/^/\=Mess()/n', 'E794:') - CheckDefFailure(['let var: dict<number'], 'E1009:') + CheckDefFailure(['var var: dict<number'], 'E1009:') CheckDefFailure(['w:foo: number = 10'], 'E488: Trailing characters: : number = 1') @@ -657,7 +658,7 @@ def Test_assignment_failure() enddef def Test_assign_list() - let l: list<string> = [] + var l: list<string> = [] l[0] = 'value' assert_equal('value', l[0]) @@ -667,7 +668,7 @@ def Test_assign_list() assert_equal('asdf', l[-1]) assert_equal('value', l[-2]) - let nrl: list<number> = [] + var nrl: list<number> = [] for i in range(5) nrl[i] = i endfor @@ -675,7 +676,7 @@ def Test_assign_list() enddef def Test_assign_dict() - let d: dict<string> = {} + var d: dict<string> = {} d['key'] = 'value' assert_equal('value', d['key']) @@ -683,7 +684,7 @@ def Test_assign_dict() assert_equal('qwerty', d[123]) assert_equal('qwerty', d['123']) - let nrd: dict<number> = {} + var nrd: dict<number> = {} for i in range(3) nrd[i] = i endfor @@ -691,12 +692,12 @@ def Test_assign_dict() enddef def Test_assign_dict_unknown_type() - let lines =<< trim END + var lines =<< trim END vim9script - let mylist = [] + var mylist = [] mylist += [#{one: 'one'}] def Func() - let dd = mylist[0] + var dd = mylist[0] assert_equal('one', dd.one) enddef Func() @@ -706,10 +707,10 @@ def Test_assign_dict_unknown_type() # doesn't work yet #lines =<< trim END # vim9script - # let mylist = [[]] + # var mylist = [[]] # mylist[0] += [#{one: 'one'}] # def Func() - # let dd = mylist[0][0] + # var dd = mylist[0][0] # assert_equal('one', dd.one) # enddef # Func() @@ -719,13 +720,13 @@ enddef def Test_assign_lambda() # check if assign a lambda to a variable which type is func or any. - let lines =<< trim END + var lines =<< trim END vim9script - let FuncRef = {->123} + var FuncRef = {->123} assert_equal(123, FuncRef()) - let FuncRef_Func: func = {->123} + var FuncRef_Func: func = {->123} assert_equal(123, FuncRef_Func()) - let FuncRef_Any: any = {->123} + var FuncRef_Any: any = {->123} assert_equal(123, FuncRef_Any()) END CheckScriptSuccess(lines) diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim index f63ecfc71..2f82b8dd3 100644 --- a/src/testdir/test_vim9_script.vim +++ b/src/testdir/test_vim9_script.vim @@ -193,21 +193,21 @@ def Test_wrong_type() enddef def Test_const() - CheckDefFailure(['const var = 234', 'var = 99'], 'E1018:') - CheckDefFailure(['const one = 234', 'let one = 99'], 'E1017:') - CheckDefFailure(['const list = [1, 2]', 'let list = [3, 4]'], 'E1017:') - CheckDefFailure(['const two'], 'E1021:') - CheckDefFailure(['const &option'], 'E996:') + CheckDefFailure(['final var = 234', 'var = 99'], 'E1018:') + CheckDefFailure(['final one = 234', 'let one = 99'], 'E1017:') + CheckDefFailure(['final list = [1, 2]', 'let list = [3, 4]'], 'E1017:') + CheckDefFailure(['final two'], 'E1125:') + CheckDefFailure(['final &option'], 'E996:') let lines =<< trim END - const list = [1, 2, 3] + final list = [1, 2, 3] list[0] = 4 list->assert_equal([4, 2, 3]) - const! other = [5, 6, 7] + const other = [5, 6, 7] other->assert_equal([5, 6, 7]) let varlist = [7, 8] - const! constlist = [1, varlist, 3] + const constlist = [1, varlist, 3] varlist[0] = 77 # TODO: does not work yet # constlist[1][1] = 88 @@ -216,7 +216,7 @@ def Test_const() constlist->assert_equal([1, [77, 88], 3]) let vardict = #{five: 5, six: 6} - const! constdict = #{one: 1, two: vardict, three: 3} + const constdict = #{one: 1, two: vardict, three: 3} vardict['five'] = 55 # TODO: does not work yet # constdict['two']['six'] = 66 @@ -229,35 +229,35 @@ enddef def Test_const_bang() let lines =<< trim END - const! var = 234 + const var = 234 var = 99 END CheckDefExecFailure(lines, 'E1018:', 2) CheckScriptFailure(['vim9script'] + lines, 'E46:', 3) lines =<< trim END - const! ll = [2, 3, 4] + const ll = [2, 3, 4] ll[0] = 99 END CheckDefExecFailure(lines, 'E1119:', 2) CheckScriptFailure(['vim9script'] + lines, 'E741:', 3) lines =<< trim END - const! ll = [2, 3, 4] + const ll = [2, 3, 4] ll[3] = 99 END CheckDefExecFailure(lines, 'E1118:', 2) CheckScriptFailure(['vim9script'] + lines, 'E684:', 3) lines =<< trim END - const! dd = #{one: 1, two: 2} + const dd = #{one: 1, two: 2} dd["one"] = 99 END CheckDefExecFailure(lines, 'E1121:', 2) CheckScriptFailure(['vim9script'] + lines, 'E741:', 3) lines =<< trim END - const! dd = #{one: 1, two: 2} + const dd = #{one: 1, two: 2} dd["three"] = 99 END CheckDefExecFailure(lines, 'E1120:') @@ -2532,6 +2532,12 @@ enddef def Test_let_declaration_fails() let lines =<< trim END vim9script + final var: string + END + CheckScriptFailure(lines, 'E1125:') + + lines =<< trim END + vim9script const var: string END CheckScriptFailure(lines, 'E1021:') diff --git a/src/version.c b/src/version.c index 282c04ef9..03a5581f0 100644 --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1744, +/**/ 1743, /**/ 1742, @@ -2135,9 +2135,9 @@ typedef enum { } estack_arg_T; // Flags for assignment functions. -#define LET_IS_CONST 1 // ":const" -#define LET_FORCEIT 2 // ":const!" (LET_IS_CONST is also set) -#define LET_NO_COMMAND 4 // "var = expr" without ":let" or ":const" +#define ASSIGN_FINAL 1 // ":final" +#define ASSIGN_CONST 2 // ":const" +#define ASSIGN_NO_DECL 4 // "name = expr" without ":let" or ":const" #include "ex_cmds.h" // Ex command defines #include "spell.h" // spell checking stuff diff --git a/src/vim9compile.c b/src/vim9compile.c index 5d0ccb659..2d640155f 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -4562,8 +4562,12 @@ vim9_declare_error(char_u *name) /* * Compile declaration and assignment: - * "let var", "let var = expr", "const var = expr" and "var = expr" - * "arg" points to "var". + * "let name" + * "var name = expr" + * "final name = expr" + * "const name = expr" + * "name = expr" + * "arg" points to "name". * Return NULL for an error. * Return "arg" if it does not look like a variable list. */ @@ -4588,7 +4592,8 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx) type_T *member_type = &t_any; char_u *name = NULL; char_u *sp; - int is_decl = cmdidx == CMD_let || cmdidx == CMD_const; + int is_decl = cmdidx == CMD_let || cmdidx == CMD_var + || cmdidx == CMD_final || cmdidx == CMD_const; // Skip over the "var" or "[var, var]" to get to any "=". p = skip_var_list(arg, TRUE, &var_count, &semicolon, TRUE); @@ -4729,7 +4734,7 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx) long numval; dest = dest_option; - if (cmdidx == CMD_const) + if (cmdidx == CMD_final || cmdidx == CMD_const) { emsg(_(e_const_option)); goto theend; @@ -4968,7 +4973,7 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx) && var_wrong_func_name(name, TRUE)) goto theend; lvar = reserve_local(cctx, var_start, varlen, - cmdidx == CMD_const, type); + cmdidx == CMD_final || cmdidx == CMD_const, type); if (lvar == NULL) goto theend; new_local = TRUE; @@ -5119,6 +5124,11 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx) cctx, FALSE) == FAIL) goto theend; } + else if (cmdidx == CMD_final) + { + emsg(_(e_final_requires_a_value)); + goto theend; + } else if (cmdidx == CMD_const) { emsg(_(e_const_requires_a_value)); @@ -5283,9 +5293,9 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx) } else { - if (is_decl && eap->forceit && cmdidx == CMD_const - && (dest == dest_script || dest == dest_local)) - // ":const! var": lock the value, but not referenced variables + if (is_decl && cmdidx == CMD_const + && (dest == dest_script || dest == dest_local)) + // ":const var": lock the value, but not referenced variables generate_LOCKCONST(cctx); switch (dest) @@ -6915,7 +6925,7 @@ compile_def_function(ufunc_T *ufunc, int set_return_type, cctx_T *outer_cctx) // Expression or function call. if (ea.cmdidx != CMD_eval) { - // CMD_let cannot happen, compile_assignment() above is used + // CMD_var cannot happen, compile_assignment() above is used iemsg("Command from find_ex_command() not handled"); goto erret; } @@ -6967,6 +6977,8 @@ compile_def_function(ufunc_T *ufunc, int set_return_type, cctx_T *outer_cctx) break; case CMD_let: + case CMD_var: + case CMD_final: case CMD_const: line = compile_assignment(p, &ea, ea.cmdidx, &cctx); if (line == p) diff --git a/src/vim9execute.c b/src/vim9execute.c index 02d2c30c0..955c3aa4d 100644 --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -729,7 +729,7 @@ store_var(char_u *name, typval_T *tv) funccal_entry_T entry; save_funccal(&entry); - set_var_const(name, NULL, tv, FALSE, LET_NO_COMMAND); + set_var_const(name, NULL, tv, FALSE, ASSIGN_NO_DECL); restore_funccal(); } diff --git a/src/vim9script.c b/src/vim9script.c index 74d0579f3..399c4a7b0 100644 --- a/src/vim9script.c +++ b/src/vim9script.c @@ -97,6 +97,8 @@ ex_export(exarg_T *eap) switch (eap->cmdidx) { case CMD_let: + case CMD_var: + case CMD_final: case CMD_const: case CMD_def: // case CMD_class: @@ -508,9 +510,12 @@ vim9_declare_scriptvar(exarg_T *eap, char_u *arg) int called_emsg_before = called_emsg; typval_T init_tv; - if (eap->cmdidx == CMD_const) + if (eap->cmdidx == CMD_final || eap->cmdidx == CMD_const) { - emsg(_(e_const_requires_a_value)); + if (eap->cmdidx == CMD_final) + emsg(_(e_final_requires_a_value)); + else + emsg(_(e_const_requires_a_value)); return arg + STRLEN(arg); } |