]> granicus.if.org Git - vim/commitdiff
patch 8.2.4589: cannot index the g: dictionary v8.2.4589
authorBram Moolenaar <Bram@vim.org>
Fri, 18 Mar 2022 19:44:48 +0000 (19:44 +0000)
committerBram Moolenaar <Bram@vim.org>
Fri, 18 Mar 2022 19:44:48 +0000 (19:44 +0000)
Problem:    Cannot index the g: dictionary.
Solution:   Recognize using "g:[key]". (closes #9969)

src/eval.c
src/ex_docmd.c
src/testdir/test_vim9_assign.vim
src/version.c
src/vim9compile.c

index 3f6be184797418920fba046efad8ea8f94fb2841..8d1e4fdf7ebcd023a66319d21e6ce57aa504b145 100644 (file)
@@ -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;
index 4066f8de94d299a007ac72c89590fdbe99fa23d1..463d840780cdb2c99a51cf91d9380c910f93ae8e 100644 (file)
@@ -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;
 
index 37ca2aee467f2b508226892f85e74ee78b93a6cc..d2d7217b537bec5eadf5acf62e302021ac9fea8d 100644 (file)
@@ -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
index 6c59f951c5b202d41a9f9436c1cab14c9441ebf1..6f86d2bb9ddcebb9dc37998522db9d42381e55b4 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4589,
 /**/
     4588,
 /**/
index fa5f067f5df227e5f4dd9825d74704102585347c..e6c2233a75f4d7746713479af27b38debce157ec 100644 (file)
@@ -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);