changeset 27030:c8809b8d19de v8.2.4044

patch 8.2.4044: Vim9: no error when importing the same script twice Commit: https://github.com/vim/vim/commit/7c24dfddc28776eeff7464982ae5b94e187b6135 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Jan 8 17:03:55 2022 +0000 patch 8.2.4044: Vim9: no error when importing the same script twice Problem: Vim9: no error when importing the same script twice. Solution: Give an error, unless it is a reload.
author Bram Moolenaar <Bram@vim.org>
date Sat, 08 Jan 2022 18:15:02 +0100
parents 07308e9dd7dc
children 348fe9745475
files src/errors.h src/testdir/test_vim9_import.vim src/version.c src/vim9script.c
diffstat 4 files changed, 51 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/src/errors.h
+++ b/src/errors.h
@@ -2891,3 +2891,5 @@ EXTERN char e_cannot_unlet_imported_item
 	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"));
--- a/src/testdir/test_vim9_import.vim
+++ b/src/testdir/test_vim9_import.vim
@@ -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')
 
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    4044,
+/**/
     4043,
 /**/
     4042,
--- a/src/vim9script.c
+++ b/src/vim9script.c
@@ -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;