]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 8.2.0368: Vim9: import that redefines local variable does not fail v8.2.0368
authorBram Moolenaar <Bram@vim.org>
Mon, 9 Mar 2020 18:25:27 +0000 (19:25 +0100)
committerBram Moolenaar <Bram@vim.org>
Mon, 9 Mar 2020 18:25:27 +0000 (19:25 +0100)
Problem:    Vim9: import that redefines local variable does not fail.
Solution:   Check for already defined symbols.

src/proto/vim9compile.pro
src/proto/vim9script.pro
src/testdir/test_vim9_script.vim
src/version.c
src/vim9compile.c
src/vim9script.c

index 61a628149ff498fd92d657aff21289155b770330..6905fc28ab52bcffd9080bb3f3a49873e3cc9389 100644 (file)
@@ -1,4 +1,5 @@
 /* vim9compile.c */
+int check_defined(char_u *p, int len, cctx_T *cctx);
 char_u *skip_type(char_u *start);
 type_T *parse_type(char_u **arg, garray_T *type_list);
 char *vartype_name(vartype_T type);
index 18edb8698e3ac119c1d1d536a56dc38a81d069a9..1d8575dc224adb521c86bd2cc065be6edc321cd5 100644 (file)
@@ -5,5 +5,5 @@ void ex_export(exarg_T *eap);
 void free_imports(int sid);
 void ex_import(exarg_T *eap);
 int find_exported(int sid, char_u **argp, int *name_len, ufunc_T **ufunc, type_T **type);
-char_u *handle_import(char_u *arg_start, garray_T *gap, int import_sid);
+char_u *handle_import(char_u *arg_start, garray_T *gap, int import_sid, void *cctx);
 /* vim: set ft=c : */
index fb07d4596f02aa394120a27e2de52ea6f24b35a9..c5dd1d376d1e2ec6b0701f968a23c3569806615a 100644 (file)
@@ -362,7 +362,7 @@ let s:export_script_lines =<< trim END
   enddef
 END
 
-def Test_vim9script()
+def Test_vim9_import_export()
   let import_script_lines =<< trim END
     vim9script
     import {exported, Exported} from './Xexport.vim'
@@ -449,6 +449,33 @@ def Test_vim9script()
   writefile(import_not_exported_lines, 'Ximport.vim')
   assert_fails('source Ximport.vim', 'E1049:')
 
+  " try to import something that is already defined
+  let import_already_defined =<< trim END
+    vim9script
+    let exported = 'something'
+    import exported from './Xexport.vim'
+  END
+  writefile(import_already_defined, 'Ximport.vim')
+  assert_fails('source Ximport.vim', 'E1073:')
+
+  " try to import something that is already defined
+  import_already_defined =<< trim END
+    vim9script
+    let exported = 'something'
+    import * as exported from './Xexport.vim'
+  END
+  writefile(import_already_defined, 'Ximport.vim')
+  assert_fails('source Ximport.vim', 'E1073:')
+
+  " try to import something that is already defined
+  import_already_defined =<< trim END
+    vim9script
+    let exported = 'something'
+    import {exported} from './Xexport.vim'
+  END
+  writefile(import_already_defined, 'Ximport.vim')
+  assert_fails('source Ximport.vim', 'E1073:')
+
   " import a very long name, requires making a copy
   let import_long_name_lines =<< trim END
     vim9script
@@ -482,10 +509,11 @@ def Test_vim9script()
     vim9script
     import {exported name} from './Xexport.vim'
   END
-  writefile(import_missing_comma_lines, 'Ximport.vim')
-  assert_fails('source Ximport.vim', 'E1046:')
+  writefile(import_missing_comma_lines, 'Ximport3.vim')
+  assert_fails('source Ximport3.vim', 'E1046:')
 
   delete('Ximport.vim')
+  delete('Ximport3.vim')
   delete('Xexport.vim')
 
   " Check that in a Vim9 script 'cpo' is set to the Vim default.
index 0c0cebed269453c1bd1aa06d8c11073e6332a0d0..b02d56ad6cd80751ae077cb03148d2017df393a3 100644 (file)
@@ -738,6 +738,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    368,
 /**/
     367,
 /**/
index 6618b6aceb43ef15a05b369497f35861d545711f..38b904d2935b67879fed804b06e58a83cbf3c395 100644 (file)
@@ -203,6 +203,25 @@ lookup_script(char_u *name, size_t len)
     return di == NULL ? FAIL: OK;
 }
 
+/*
+ * Check if "p[len]" is already defined, either in script "import_sid" or in
+ * compilation context "cctx".
+ * Return FAIL and give an error if it defined.
+ */
+    int
+check_defined(char_u *p, int len, cctx_T *cctx)
+{
+    if (lookup_script(p, len) == OK
+           || (cctx != NULL
+               && (lookup_local(p, len, cctx) >= 0
+                   || find_imported(p, len, cctx) != NULL)))
+    {
+       semsg("E1073: imported name already defined: %s", p);
+       return FAIL;
+    }
+    return OK;
+}
+
     static type_T *
 get_list_type(type_T *member_type, garray_T *type_list)
 {
@@ -3812,7 +3831,7 @@ theend:
     static char_u *
 compile_import(char_u *arg, cctx_T *cctx)
 {
-    return handle_import(arg, &cctx->ctx_imports, 0);
+    return handle_import(arg, &cctx->ctx_imports, 0, cctx);
 }
 
 /*
index 6cea96bd044e95a21ffa9d05da6fbfd5fa977e75..ce5cfec922ceaef11f3a9d69842f7582706ef534 100644 (file)
@@ -143,7 +143,8 @@ ex_import(exarg_T *eap)
        emsg(_(e_needs_vim9));
     else
     {
-       char_u *cmd_end = handle_import(eap->arg, NULL, current_sctx.sc_sid);
+       char_u *cmd_end = handle_import(eap->arg, NULL,
+                                                   current_sctx.sc_sid, NULL);
 
        if (cmd_end != NULL)
            eap->nextcmd = check_nextcmd(cmd_end);
@@ -238,7 +239,7 @@ find_exported(
  * Returns a pointer to after the command or NULL in case of failure
  */
     char_u *
-handle_import(char_u *arg_start, garray_T *gap, int import_sid)
+handle_import(char_u *arg_start, garray_T *gap, int import_sid, void *cctx)
 {
     char_u     *arg = arg_start;
     char_u     *cmd_end;
@@ -278,6 +279,8 @@ handle_import(char_u *arg_start, garray_T *gap, int import_sid)
                    ++arg;
            as_len = (int)(arg - as_ptr);
            arg = skipwhite(arg);
+           if (check_defined(as_ptr, as_len, cctx) == FAIL)
+               return NULL;
        }
        else if (*arg_start == '*')
        {
@@ -389,6 +392,9 @@ handle_import(char_u *arg_start, garray_T *gap, int import_sid)
            if (idx < 0 && ufunc == NULL)
                return NULL;
 
+           if (check_defined(name, name_len, cctx) == FAIL)
+               return NULL;
+
            imported = new_imported(gap != NULL ? gap
                                       : &SCRIPT_ITEM(import_sid)->sn_imports);
            if (imported == NULL)