]> granicus.if.org Git - vim/commitdiff
patch 8.2.0755: Vim9: No error when variable initializer is not a constant v8.2.0755
authorBram Moolenaar <Bram@vim.org>
Fri, 15 May 2020 16:17:28 +0000 (18:17 +0200)
committerBram Moolenaar <Bram@vim.org>
Fri, 15 May 2020 16:17:28 +0000 (18:17 +0200)
Problem:    Vim9: No error when variable initializer is not a constant.
Solution:   Return FAIL when trying to get a variable value.  Do not execute a
            script when an error is deteted in the first or second phase.

src/eval.c
src/testdir/test_vim9_script.vim
src/version.c
src/vim9script.c

index b3fe650ee88858ddf12640191c96c7f110432f50..77359dccaa0ba4c36f3223b9d5b96e59c1365f21 100644 (file)
@@ -2695,6 +2695,8 @@ eval7(
        {
            if (**arg == '(')           // recursive!
                ret = eval_func(arg, s, len, rettv, flags, NULL);
+           else if (flags & EVAL_CONSTANT)
+               ret = FAIL;
            else if (evaluate)
                ret = get_var_tv(s, len, rettv, NULL, TRUE, FALSE);
            else
index 6b6228e5ed3e5b5b19a23f239cdb6eec8b4c385e..fd1dbc8c2fcdb625596df80efa21a3bb7f67ecdc 100644 (file)
@@ -494,8 +494,8 @@ let s:export_script_lines =<< trim END
   def Concat(arg: string): string
     return name .. arg
   enddef
-  let g:result: string = Concat('bie')
-  let g:localname = name
+  g:result = Concat('bie')
+  g:localname = name
 
   export const CONST = 1234
   export let exported = 9876
@@ -1747,10 +1747,34 @@ def Test_let_missing_type()
     endfunc
     let val = GetValue() 
   END
-  writefile(lines, 'Xfinished')
-  assert_fails('source Xfinished', 'E1091:')
+  CheckScriptFailure(lines, 'E1091:')
 
-  delete('Xfinished')
+  lines =<< trim END
+    vim9script
+    let var = g:unkown
+  END
+  CheckScriptFailure(lines, 'E1091:')
+
+  " TODO: eventually this would work
+  lines =<< trim END
+    vim9script
+    let var = has('eval')
+  END
+  CheckScriptFailure(lines, 'E1091:')
+
+  " TODO: eventually this would work
+  lines =<< trim END
+    vim9script
+    let var = len('string')
+  END
+  CheckScriptFailure(lines, 'E1091:')
+
+  lines =<< trim END
+    vim9script
+    let nr: number = 123
+    let var = nr
+  END
+  CheckScriptFailure(lines, 'E1091:')
 enddef
 
 def Test_forward_declaration()
index 8ff5161e72fc52efcb18d7711d9ccd640c51af11..1f77ddc3f7e56995232b61c6f953490412afa4b2 100644 (file)
@@ -746,6 +746,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    755,
 /**/
     754,
 /**/
index 4d7e8ee46fe4c01b508fed0b099a20ea190789f2..e213d61f1da569139564e8498930b8acadeb3fbf 100644 (file)
@@ -37,6 +37,7 @@ ex_vim9script(exarg_T *eap)
     garray_T       func_ga;
     int                    idx;
     ufunc_T        *ufunc;
+    int                    start_called_emsg = called_emsg;
 
     if (!getline_equal(eap->getline, eap->cookie, getsourceline))
     {
@@ -66,7 +67,7 @@ ex_vim9script(exarg_T *eap)
     // The types are recognized, so that they can be used when compiling a
     // function.
     gap = source_get_line_ga(eap->cookie);
-    for (;;)
+    while (called_emsg == start_called_emsg)
     {
        char_u      *line;
        char_u      *p;
@@ -132,22 +133,29 @@ ex_vim9script(exarg_T *eap)
        }
        else if (checkforcmd(&p, "finish", 4))
        {
-           // TODO: this should not happen below "if false".
-           // Use "if cond | finish | endif as a workaround.
            break;
        }
     }
 
     // Compile the :def functions.
-    for (idx = 0; idx < func_ga.ga_len; ++idx)
+    for (idx = 0; idx < func_ga.ga_len && called_emsg == start_called_emsg; ++idx)
     {
        ufunc = ((ufunc_T **)(func_ga.ga_data))[idx];
        compile_def_function(ufunc, FALSE, NULL);
     }
     ga_clear(&func_ga);
 
-    // Return to process the commands at the script level.
-    source_use_line_ga(eap->cookie);
+    if (called_emsg == start_called_emsg)
+    {
+       // Return to process the commands at the script level.
+       source_use_line_ga(eap->cookie);
+    }
+    else
+    {
+       // If there was an error in the first or second phase then don't
+       // execute the script lines.
+       do_finish(eap, FALSE);
+    }
 }
 
 /*