]> granicus.if.org Git - vim/commitdiff
patch 8.2.4044: Vim9: no error when importing the same script twice v8.2.4044
authorBram Moolenaar <Bram@vim.org>
Sat, 8 Jan 2022 17:03:55 +0000 (17:03 +0000)
committerBram Moolenaar <Bram@vim.org>
Sat, 8 Jan 2022 17:03:55 +0000 (17:03 +0000)
Problem:    Vim9: no error when importing the same script twice.
Solution:   Give an error, unless it is a reload.

src/errors.h
src/testdir/test_vim9_import.vim
src/version.c
src/vim9script.c

index 9facb82c4afde50cc6c4b4664e83149ad6139f01..8e7ffee18df7f76e72fd62b1c3e76443439743d2 100644 (file)
@@ -2891,3 +2891,5 @@ EXTERN char e_cannot_unlet_imported_item_str[]
        INIT(= N_("E1260: Cannot unlet an imported item: %s"));
 EXTERN char e_cannot_import_dot_vim_without_using_as[]
        INIT(= N_("E1261: Cannot import .vim without using \"as\""));
+EXTERN char e_cannot_import_same_script_twice_str[]
+       INIT(= N_("E1262: Cannot import the same script twice: %s"));
index 9d09c63f6ead38ca3b50a461c9ee4bc5ac68a290..4e57f742f6f9d9147dbcd73850d5000e1cea4e84 100644 (file)
@@ -189,25 +189,15 @@ def Test_vim9_import_export()
   writefile(import_star_as_lines_dot_space, 'Ximport.vim')
   assert_fails('source Ximport.vim', 'E1074:', '', 1, 'Func')
 
-  var import_func_duplicated =<< trim END
+  writefile(s:export_script_lines, 'Xexport2.vim')
+  var import_as_duplicated =<< trim END
     vim9script
     import './Xexport.vim' as expo
-    import './Xexport.vim' as expo
-
-    ExportedInc()
+    import './Xexport2.vim' as expo
   END
-  writefile(import_func_duplicated, 'Ximport.vim')
+  writefile(import_as_duplicated, 'Ximport.vim')
   assert_fails('source Ximport.vim', 'E1073:', '', 3, 'Ximport.vim')
-
-  var import_star_as_duplicated =<< trim END
-    vim9script
-    import './Xexport.vim' as Export
-    var some = 'other'
-    import './Xexport.vim' as Export
-    defcompile
-  END
-  writefile(import_star_as_duplicated, 'Ximport.vim')
-  assert_fails('source Ximport.vim', 'E1073:', '', 4, 'Ximport.vim')
+  delete('Xexport2.vim')
 
   var import_star_as_lines_script_no_dot =<< trim END
     vim9script
@@ -429,11 +419,20 @@ def Test_import_fails()
       export var Ref = TheFunc
   END
   writefile([], 'Xthat.vim')
+
   lines =<< trim END
       import './Xthat.vim' as That
       That()
   END
   CheckDefAndScriptFailure(lines, ['E1094:', 'E1236: Cannot use That itself'])
+
+  lines =<< trim END
+      import './Xthat.vim' as one
+      import './Xthat.vim' as two
+  END
+  CheckScriptFailure(lines, 'E1262:')
+
+  delete('Xthat.vim')
  
   mkdir('Ximport')
 
@@ -773,7 +772,14 @@ def Test_vim9_funcref()
       g:result = Xsort.FastSort()
     enddef
     Test()
+  END
+  writefile(lines, 'Xscript.vim')
+  source Xscript.vim
+  assert_equal([4, 3, 2, 1, 0], g:result)
+  unlet g:result
 
+  lines =<< trim END
+    vim9script
     # using a function imported with "as"
     import './Xsort.vim' as anAlias
     assert_equal('yes', anAlias.GetString('yes'))
@@ -790,10 +796,6 @@ def Test_vim9_funcref()
   END
   writefile(lines, 'Xscript.vim')
 
-  source Xscript.vim
-  assert_equal([4, 3, 2, 1, 0], g:result)
-
-  unlet g:result
   delete('Xsort.vim')
   delete('Xscript.vim')
 
index cdfadebdad77c66f50cfcfca28d4ea879c7f95b1..86ab08594acabb5ad4d8ae68a3539598e256c50f 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4044,
 /**/
     4043,
 /**/
index e5e26959a4aa4283e99fa57e4c14cd09e791abdb..3ebeab366ae5ebc814710f3c848a4c93555f5d5c 100644 (file)
@@ -374,6 +374,8 @@ handle_import(
     int                sid = -1;
     int                res;
     long       start_lnum = SOURCING_LNUM;
+    garray_T   *import_gap;
+    int                i;
 
     // The name of the file can be an expression, which must evaluate to a
     // string.
@@ -440,6 +442,24 @@ handle_import(
        goto erret;
     }
 
+    import_gap = gap != NULL ? gap : &SCRIPT_ITEM(import_sid)->sn_imports;
+    for (i = 0; i < import_gap->ga_len; ++i)
+    {
+       imported_T *import = (imported_T *)import_gap->ga_data + i;
+
+       if (import->imp_sid == sid)
+       {
+           if (import->imp_flags & IMP_FLAGS_RELOAD)
+           {
+               // encountering same script first ime on a reload is OK
+               import->imp_flags &= ~IMP_FLAGS_RELOAD;
+               break;
+           }
+           semsg(_(e_cannot_import_same_script_twice_str), tv.vval.v_string);
+           goto erret;
+       }
+    }
+
     // Allow for the "as Name" to be in the next line.
     nextarg = eval_next_non_blank(expr_end, evalarg, &getnext);
     if (STRNCMP("as", nextarg, 2) == 0 && IS_WHITE_OR_NUL(nextarg[2]))
@@ -494,22 +514,16 @@ handle_import(
        imported_T  *imported;
 
        imported = find_imported(as_name, STRLEN(as_name), cctx);
-       if (imported != NULL && imported->imp_sid == sid)
+       if (imported != NULL && imported->imp_sid != sid)
        {
-           if (imported->imp_flags & IMP_FLAGS_RELOAD)
-               // import already defined on a previous script load
-               imported->imp_flags &= ~IMP_FLAGS_RELOAD;
-           else
-           {
-               semsg(_(e_name_already_defined_str), as_name);
-               goto erret;
-           }
+           semsg(_(e_name_already_defined_str), as_name);
+           goto erret;
        }
-       else if (check_defined(as_name, STRLEN(as_name), cctx, FALSE) == FAIL)
+       else if (imported == NULL
+               && check_defined(as_name, STRLEN(as_name), cctx, FALSE) == FAIL)
            goto erret;
 
-       imported = new_imported(gap != NULL ? gap
-                                       : &SCRIPT_ITEM(import_sid)->sn_imports);
+       imported = new_imported(import_gap);
        if (imported == NULL)
            goto erret;
        imported->imp_name = as_name;