vim-patch:8.2.1306: checking for first character of dict key is inconsistent

Problem:    Checking for first character of dict key is inconsistent.
Solution:   Add eval_isdictc(). (closes vim/vim#6546)

b13ab99908

Omit handle_subscript() change: only affects Vim9 script.

Co-authored-by: Bram Moolenaar <Bram@vim.org>
This commit is contained in:
zeertzjq 2022-11-06 06:35:34 +08:00
parent e03f23189d
commit 1f0bf65ad6
3 changed files with 19 additions and 5 deletions

View File

@ -3418,7 +3418,7 @@ static int eval_index(char **arg, typval_T *rettv, int evaluate, int verbose)
if (**arg == '.') { if (**arg == '.') {
// dict.name // dict.name
key = *arg + 1; key = *arg + 1;
for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; len++) {} for (len = 0; eval_isdictc(key[len]); len++) {}
if (len == 0) { if (len == 0) {
return FAIL; return FAIL;
} }
@ -6695,7 +6695,7 @@ const char *find_name_end(const char *arg, const char **expr_start, const char *
&& (eval_isnamec(*p) && (eval_isnamec(*p)
|| *p == '{' || *p == '{'
|| ((flags & FNE_INCL_BR) && (*p == '[' || ((flags & FNE_INCL_BR) && (*p == '['
|| (*p == '.' && eval_isnamec1(p[1])))) || (*p == '.' && eval_isdictc(p[1]))))
|| mb_nest != 0 || mb_nest != 0
|| br_nest != 0); MB_PTR_ADV(p)) { || br_nest != 0); MB_PTR_ADV(p)) {
if (*p == '\'') { if (*p == '\'') {
@ -6808,18 +6808,25 @@ static char *make_expanded_name(const char *in_start, char *expr_start, char *ex
/// @return true if character "c" can be used in a variable or function name. /// @return true if character "c" can be used in a variable or function name.
/// Does not include '{' or '}' for magic braces. /// Does not include '{' or '}' for magic braces.
int eval_isnamec(int c) bool eval_isnamec(int c)
{ {
return ASCII_ISALNUM(c) || c == '_' || c == ':' || c == AUTOLOAD_CHAR; return ASCII_ISALNUM(c) || c == '_' || c == ':' || c == AUTOLOAD_CHAR;
} }
/// @return true if character "c" can be used as the first character in a /// @return true if character "c" can be used as the first character in a
/// variable or function name (excluding '{' and '}'). /// variable or function name (excluding '{' and '}').
int eval_isnamec1(int c) bool eval_isnamec1(int c)
{ {
return ASCII_ISALPHA(c) || c == '_'; return ASCII_ISALPHA(c) || c == '_';
} }
/// @return true if character "c" can be used as the first character of a
/// dictionary key.
bool eval_isdictc(int c)
{
return ASCII_ISALNUM(c) || c == '_';
}
/// Get typval_T v: variable value. /// Get typval_T v: variable value.
typval_T *get_vim_var_tv(int idx) typval_T *get_vim_var_tv(int idx)
{ {

View File

@ -276,7 +276,7 @@ func Test_let_errors()
let s = "var" let s = "var"
let var = 1 let var = 1
call assert_fails('let var += [1,2]', 'E734:') call assert_fails('let var += [1,2]', 'E734:')
call assert_fails('let {s}.1 = 2', 'E15:') call assert_fails('let {s}.1 = 2', 'E18:')
call assert_fails('let a[1] = 5', 'E121:') call assert_fails('let a[1] = 5', 'E121:')
let l = [[1,2]] let l = [[1,2]]
call assert_fails('let l[:][0] = [5]', 'E708:') call assert_fails('let l[:][0] = [5]', 'E708:')

View File

@ -289,6 +289,13 @@ func Test_dict_func()
call assert_equal('xxx3', Fn('xxx')) call assert_equal('xxx3', Fn('xxx'))
endfunc endfunc
func Test_dict_assign()
let d = {}
let d.1 = 1
let d._ = 2
call assert_equal({'1': 1, '_': 2}, d)
endfunc
" Function in script-local List or Dict " Function in script-local List or Dict
func Test_script_local_dict_func() func Test_script_local_dict_func()
let g:dict = {} let g:dict = {}