diff options
author | Bram Moolenaar <Bram@vim.org> | 2020-07-27 21:43:28 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2020-07-27 21:43:28 +0200 |
commit | b13ab99908097d54e21ab5adad22f4ad2a8ec688 (patch) | |
tree | 8b35ffaf45b3ed9b21bce9bc8f6422b31564be69 | |
parent | 622b3568fa1baf07671d31390815fb0a55a99891 (diff) | |
download | vim-git-b13ab99908097d54e21ab5adad22f4ad2a8ec688.tar.gz |
patch 8.2.1306: checking for first character of dict key is inconsistentv8.2.1306
Problem: Checking for first character of dict key is inconsistent.
Solution: Add eval_isdictc(). (closes #6546)
-rw-r--r-- | src/eval.c | 21 | ||||
-rw-r--r-- | src/proto/eval.pro | 1 | ||||
-rw-r--r-- | src/testdir/test_let.vim | 2 | ||||
-rw-r--r-- | src/testdir/test_listdict.vim | 7 | ||||
-rw-r--r-- | src/testdir/test_vim9_expr.vim | 13 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim9compile.c | 4 |
7 files changed, 40 insertions, 10 deletions
diff --git a/src/eval.c b/src/eval.c index 6d3d19ee8..81913c7a3 100644 --- a/src/eval.c +++ b/src/eval.c @@ -3464,7 +3464,7 @@ eval_index( * dict.name */ key = *arg + 1; - for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) + for (len = 0; eval_isdictc(key[len]); ++len) ; if (len == 0) return FAIL; @@ -4997,7 +4997,7 @@ find_name_end( && (eval_isnamec(*p) || (*p == '{' && !vim9script) || ((flags & FNE_INCL_BR) && (*p == '[' - || (*p == '.' && eval_isnamec1(p[1])))) + || (*p == '.' && eval_isdictc(p[1])))) || mb_nest != 0 || br_nest != 0); MB_PTR_ADV(p)) { @@ -5128,7 +5128,7 @@ make_expanded_name( int eval_isnamec(int c) { - return (ASCII_ISALNUM(c) || c == '_' || c == ':' || c == AUTOLOAD_CHAR); + return ASCII_ISALNUM(c) || c == '_' || c == ':' || c == AUTOLOAD_CHAR; } /* @@ -5138,7 +5138,17 @@ eval_isnamec(int c) int 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. + */ + int +eval_isdictc(int c) +{ + return ASCII_ISALNUM(c) || c == '_'; } /* @@ -5171,8 +5181,7 @@ handle_subscript( // the next line then consume the line break. p = eval_next_non_blank(*arg, evalarg, &getnext); if (getnext - && ((rettv->v_type == VAR_DICT && *p == '.' - && ASCII_ISALPHA(p[1])) + && ((rettv->v_type == VAR_DICT && *p == '.' && eval_isdictc(p[1])) || (*p == '-' && p[1] == '>' && (p[2] == '{' || ASCII_ISALPHA(p[2]))))) { diff --git a/src/proto/eval.pro b/src/proto/eval.pro index 5d04e01ac..a528d3e43 100644 --- a/src/proto/eval.pro +++ b/src/proto/eval.pro @@ -58,6 +58,7 @@ int get_name_len(char_u **arg, char_u **alias, int evaluate, int verbose); char_u *find_name_end(char_u *arg, char_u **expr_start, char_u **expr_end, int flags); int eval_isnamec(int c); int eval_isnamec1(int c); +int eval_isdictc(int c); int handle_subscript(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int verbose); int item_copy(typval_T *from, typval_T *to, int deep, int copyID); void echo_one(typval_T *rettv, int with_space, int *atstart, int *needclr); diff --git a/src/testdir/test_let.vim b/src/testdir/test_let.vim index 9a399e8f3..017b2a4a4 100644 --- a/src/testdir/test_let.vim +++ b/src/testdir/test_let.vim @@ -293,7 +293,7 @@ func Test_let_errors() let s = "var" let var = 1 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:') let l = [[1,2]] call assert_fails('let l[:][0] = [5]', 'E708:') diff --git a/src/testdir/test_listdict.vim b/src/testdir/test_listdict.vim index b06484699..beeda2f5b 100644 --- a/src/testdir/test_listdict.vim +++ b/src/testdir/test_listdict.vim @@ -282,6 +282,13 @@ func Test_dict_func() call assert_equal('xxx3', Fn('xxx')) 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 func Test_script_local_dict_func() let g:dict = {} diff --git a/src/testdir/test_vim9_expr.vim b/src/testdir/test_vim9_expr.vim index d7072f34b..5b46c32f9 100644 --- a/src/testdir/test_vim9_expr.vim +++ b/src/testdir/test_vim9_expr.vim @@ -1310,6 +1310,11 @@ def Test_expr_member() ]) assert_equal(1, d .one) + d = {'1': 1, '_': 2} + assert_equal(1, d + .1) + assert_equal(2, d + ._) # getting the one member should clear the dict after getting the item assert_equal('one', #{one: 'one'}.one) @@ -1330,10 +1335,16 @@ def Test_expr_member_vim9script() vim9script let d = #{one: 'one', - two: 'two'} + two: 'two', + 1: 1, + _: 2} assert_equal('one', d.one) assert_equal('one', d .one) + assert_equal(1, d + .1) + assert_equal(2, d + ._) assert_equal('one', d[ 'one' ]) diff --git a/src/version.c b/src/version.c index ec702330b..a87cc89d3 100644 --- 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 */ /**/ + 1306, +/**/ 1305, /**/ 1304, diff --git a/src/vim9compile.c b/src/vim9compile.c index 8efb1f672..1ed321146 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -3758,7 +3758,7 @@ compile_subscript( if (next != NULL && ((next[0] == '-' && next[1] == '>' && (next[2] == '{' || ASCII_ISALPHA(next[2]))) - || (next[0] == '.' && ASCII_ISALPHA(next[1])))) + || (next[0] == '.' && eval_isdictc(next[1])))) { next = next_line_from_context(cctx, TRUE); if (next == NULL) @@ -3922,7 +3922,7 @@ compile_subscript( return FAIL; // dictionary member: dict.name p = *arg; - if (eval_isnamec1(*p)) + if (eval_isdictc(*p)) while (eval_isnamec(*p)) MB_PTR_ADV(p); if (p == *arg) |