From 2e17fef225a58f478dc24ab1aaa20390c9abce57 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 18 Mar 2022 19:44:48 +0000 Subject: [PATCH] patch 8.2.4589: cannot index the g: dictionary Problem: Cannot index the g: dictionary. Solution: Recognize using "g:[key]". (closes #9969) --- src/eval.c | 3 ++- src/ex_docmd.c | 8 +++++--- src/testdir/test_vim9_assign.vim | 8 ++++++++ src/version.c | 2 ++ src/vim9compile.c | 15 +++++++++++---- 5 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/eval.c b/src/eval.c index 3f6be1847..8d1e4fdf7 100644 --- a/src/eval.c +++ b/src/eval.c @@ -929,7 +929,8 @@ get_lval( if (vim9script) { // "a: type" is declaring variable "a" with a type, not "a:". - if (p == name + 2 && p[-1] == ':') + // However, "g:[key]" is indexing a dictionary. + if (p == name + 2 && p[-1] == ':' && *p != '[') { --p; lp->ll_name_end = p; diff --git a/src/ex_docmd.c b/src/ex_docmd.c index 4066f8de9..463d84078 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -3523,12 +3523,14 @@ find_ex_command( return eap->cmd; } - if (p != eap->cmd && ( + if ((p != eap->cmd && ( // "varname[]" is an expression. *p == '[' // "varname.key" is an expression. - || (*p == '.' && (ASCII_ISALPHA(p[1]) - || p[1] == '_')))) + || (*p == '.' + && (ASCII_ISALPHA(p[1]) || p[1] == '_')))) + // g:[key] is an expression + || STRNCMP(eap->cmd, "g:[", 3) == 0) { char_u *after = eap->cmd; diff --git a/src/testdir/test_vim9_assign.vim b/src/testdir/test_vim9_assign.vim index 37ca2aee4..d2d7217b5 100644 --- a/src/testdir/test_vim9_assign.vim +++ b/src/testdir/test_vim9_assign.vim @@ -1116,6 +1116,14 @@ def Test_assignment_dict() END v9.CheckDefAndScriptSuccess(lines) + lines =<< trim END + var key = 'foo' + g:[key] = 'value' + assert_equal('value', g:foo) + unlet g:foo + END + v9.CheckDefAndScriptSuccess(lines) + lines =<< trim END var dd = {one: 1} dd.one) = 2 diff --git a/src/version.c b/src/version.c index 6c59f951c..6f86d2bb9 100644 --- a/src/version.c +++ b/src/version.c @@ -750,6 +750,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 4589, /**/ 4588, /**/ diff --git a/src/vim9compile.c b/src/vim9compile.c index fa5f067f5..e6c2233a7 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -1000,7 +1000,12 @@ generate_loadvar( break; case dest_global: if (vim_strchr(name, AUTOLOAD_CHAR) == NULL) - generate_LOAD(cctx, ISN_LOADG, 0, name + 2, type); + { + if (name[2] == NUL) + generate_instr_type(cctx, ISN_LOADGDICT, &t_dict_any); + else + generate_LOAD(cctx, ISN_LOADG, 0, name + 2, type); + } else generate_LOAD(cctx, ISN_LOADAUTO, 0, name, type); break; @@ -2413,17 +2418,19 @@ may_compile_assignment(exarg_T *eap, char_u **line, cctx_T *cctx) // Recognize an assignment if we recognize the variable // name: + // "&opt = expr" + // "$ENV = expr" + // "@r = expr" // "g:var = expr" + // "g:[key] = expr" // "local = expr" where "local" is a local var. // "script = expr" where "script" is a script-local var. // "import = expr" where "import" is an imported var - // "&opt = expr" - // "$ENV = expr" - // "@r = expr" if (*eap->cmd == '&' || *eap->cmd == '$' || *eap->cmd == '@' || ((len) > 2 && eap->cmd[1] == ':') + || STRNCMP(eap->cmd, "g:[", 3) == 0 || variable_exists(eap->cmd, len, cctx)) { *line = compile_assignment(eap->cmd, eap, CMD_SIZE, cctx); -- 2.40.0