]> granicus.if.org Git - vim/commitdiff
patch 8.2.0492: Vim9: some error messages not tested v8.2.0492
authorBram Moolenaar <Bram@vim.org>
Wed, 1 Apr 2020 19:17:24 +0000 (21:17 +0200)
committerBram Moolenaar <Bram@vim.org>
Wed, 1 Apr 2020 19:17:24 +0000 (21:17 +0200)
Problem:    Vim9: some error messages not tested.
Solution:   Add more tests.  Remove dead code.  Fix uncovered bugs.

src/testdir/test_vim9_expr.vim
src/testdir/test_vim9_script.vim
src/version.c
src/vim9compile.c
src/vim9execute.c

index 06c200dbf8f0583211868020f9c10671d7eee3a9..8f27c6d8488a3f2298e621e18818e4eddc67f89b 100644 (file)
@@ -106,6 +106,8 @@ func Test_expr2_fails()
   call CheckDefFailure("let x = 1||2", msg)
   call CheckDefFailure("let x = 1 ||2", msg)
   call CheckDefFailure("let x = 1|| 2", msg)
+
+  call CheckDefFailure("let x = 1 || xxx", 'E1001:')
 endfunc
 
 " test &&
@@ -877,7 +879,7 @@ func Test_expr7_fails()
   call CheckDefFailure("let x = 123->{x -> x + 5) }", "E451:")
 
   call CheckDefFailure("let x = &notexist", 'E113:')
-  call CheckDefExecFailure("&grepprg = [343]", 'E1051:')
+  call CheckDefFailure("&grepprg = [343]", 'E1013:')
 
   call CheckDefExecFailure("echo s:doesnt_exist", 'E121:')
   call CheckDefExecFailure("echo g:doesnt_exist", 'E121:')
index 19df73c5ef28ee966823266acf7572ba40d897cb..0c0bf83a860743ce812cacf38ef644e838d225aa 100644 (file)
@@ -31,6 +31,8 @@ endfunc
 let s:appendToMe = 'xxx'
 let s:addToMe = 111
 let g:existing = 'yes'
+let g:inc_counter = 1
+let $SOME_ENV_VAR = 'some'
 
 def Test_assignment()
   let bool1: bool = true
@@ -94,6 +96,27 @@ def Test_assignment()
   assert_equal(333, s:addToMe)
   s:newVar = 'new'
   assert_equal('new', s:newVar)
+
+  set ts=7
+  &ts += 1
+  assert_equal(8, &ts)
+  call CheckDefFailure(['&notex += 3'], 'E113:')
+  call CheckDefFailure(['&ts ..= "xxx"'], 'E1019:')
+  call CheckDefFailure(['&path += 3'], 'E1013:')
+
+  g:inc_counter += 1
+  assert_equal(2, g:inc_counter)
+
+  $SOME_ENV_VAR ..= 'more'
+  assert_equal('somemore', $SOME_ENV_VAR)
+  call CheckDefFailure(['$SOME_ENV_VAR += "more"'], 'E1013:')
+  call CheckDefFailure(['$SOME_ENV_VAR += 123'], 'E1013:')
+
+  @a = 'areg'
+  @a ..= 'add'
+  assert_equal('aregadd', @a)
+  call CheckDefFailure(['@a += "more"'], 'E1013:')
+  call CheckDefFailure(['@a += 123'], 'E1013:')
 enddef
 
 func Test_assignment_failure()
index 31f2f74bf876b93a75159ca3576944395e3a03c5..5fc599c467bda51fde20b944ce7f712841438507 100644 (file)
@@ -738,6 +738,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    492,
 /**/
     491,
 /**/
index 64ebddfb99a0241df7c2dd18208cdda3be8f39af..2726e387f756a3098338e60e6caab891ff372815 100644 (file)
@@ -277,6 +277,25 @@ get_dict_type(type_T *member_type, garray_T *type_list)
     return type;
 }
 
+/*
+ * Return the type_T for a typval.  Only for primitive types.
+ */
+    static type_T *
+typval2type(typval_T *tv)
+{
+    if (tv->v_type == VAR_NUMBER)
+       return &t_number;
+    if (tv->v_type == VAR_BOOL)
+       return &t_bool;
+    if (tv->v_type == VAR_STRING)
+       return &t_string;
+    if (tv->v_type == VAR_LIST)  // e.g. for v:oldfiles
+       return &t_list_string;
+    if (tv->v_type == VAR_DICT)  // e.g. for v:completed_item
+       return &t_dict_any;
+    return &t_any;
+}
+
 /////////////////////////////////////////////////////////////////////
 // Following generate_ functions expect the caller to call ga_grow().
 
@@ -1402,7 +1421,7 @@ parse_type_member(char_u **arg, type_T *type, garray_T *type_list)
 
 /*
  * Parse a type at "arg" and advance over it.
- * Return NULL for failure.
+ * Return &t_any for failure.
  */
     type_T *
 parse_type(char_u **arg, garray_T *type_list)
@@ -3462,7 +3481,7 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
     int                vimvaridx = -1;
     int                oplen = 0;
     int                heredoc = FALSE;
-    type_T     *type;
+    type_T     *type = &t_any;
     lvar_T     *lvar;
     char_u     *name;
     char_u     *sp;
@@ -3532,6 +3551,7 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
        else if (*arg == '$')
        {
            dest = dest_env;
+           type = &t_string;
            if (is_decl)
            {
                semsg(_("E1065: Cannot declare an environment variable: %s"), name);
@@ -3546,6 +3566,7 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
                goto theend;
            }
            dest = dest_reg;
+           type = &t_string;
            if (is_decl)
            {
                semsg(_("E1066: Cannot declare a register: %s"), name);
@@ -3563,6 +3584,8 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
        }
        else if (STRNCMP(arg, "v:", 2) == 0)
        {
+           typval_T *vtv;
+
            vimvaridx = find_vim_var(name + 2);
            if (vimvaridx < 0)
            {
@@ -3570,6 +3593,8 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
                goto theend;
            }
            dest = dest_vimvar;
+           vtv = get_vim_var_tv(vimvaridx);
+           type = typval2type(vtv);
            if (is_decl)
            {
                semsg(_("E1064: Cannot declare a v: variable: %s"), name);
@@ -3625,16 +3650,9 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
            // parse optional type: "let var: type = expr"
            p = skipwhite(p + 1);
            type = parse_type(&p, cctx->ctx_type_list);
-           if (type == NULL)
-               goto theend;
            has_type = TRUE;
        }
-       else if (idx < 0)
-       {
-           // global and new local default to "any" type
-           type = &t_any;
-       }
-       else
+       else if (idx >= 0)
        {
            lvar = ((lvar_T *)cctx->ctx_locals.ga_data) + idx;
            type = lvar->lv_type;
@@ -3700,7 +3718,9 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
     }
     else if (oplen > 0)
     {
-       int r;
+       int     r;
+       type_T  *stacktype;
+       garray_T *stack;
 
        // for "+=", "*=", "..=" etc. first load the current value
        if (*op != '=')
@@ -3709,7 +3729,7 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
            {
                case dest_option:
                    // TODO: check the option exists
-                   generate_LOAD(cctx, ISN_LOADOPT, 0, name + 1, type);
+                   generate_LOAD(cctx, ISN_LOADOPT, 0, name, type);
                    break;
                case dest_global:
                    generate_LOAD(cctx, ISN_LOADG, 0, name + 2, type);
@@ -3746,12 +3766,10 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
        if (r == FAIL)
            goto theend;
 
+       stack = &cctx->ctx_type_stack;
+       stacktype = ((type_T **)stack->ga_data)[stack->ga_len - 1];
        if (idx >= 0 && (is_decl || !has_type))
        {
-           garray_T    *stack = &cctx->ctx_type_stack;
-           type_T      *stacktype =
-                               ((type_T **)stack->ga_data)[stack->ga_len - 1];
-
            lvar = ((lvar_T *)cctx->ctx_locals.ga_data) + idx;
            if (!has_type)
            {
@@ -3767,6 +3785,8 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
                if (check_type(lvar->lv_type, stacktype, TRUE) == FAIL)
                    goto theend;
        }
+       else if (*p != '=' && check_type(type, stacktype, TRUE) == FAIL)
+           goto theend;
     }
     else if (cmdidx == CMD_const)
     {
index c082384c605dc59fc259ae581fba457d72635aa9..89e4f054b0905d4798c1b871d0557f1273a5f5e1 100644 (file)
@@ -684,6 +684,8 @@ call_def_function(
                    typval_T    optval;
                    char_u      *name = iptr->isn_arg.string;
 
+                   // This is not expected to fail, name is checked during
+                   // compilation: don't set SOURCING_LNUM.
                    if (ga_grow(&ectx.ec_stack, 1) == FAIL)
                        goto failed;
                    if (get_option_tv(&name, &optval, TRUE) == FAIL)