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.
diff --git a/src/errors.h b/src/errors.h
index 9facb82..8e7ffee 100644
--- a/src/errors.h
+++ b/src/errors.h
@@ -2891,3 +2891,5 @@
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"));
diff --git a/src/testdir/test_vim9_import.vim b/src/testdir/test_vim9_import.vim
index 9d09c63..4e57f74 100644
--- a/src/testdir/test_vim9_import.vim
+++ b/src/testdir/test_vim9_import.vim
@@ -189,25 +189,15 @@
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 @@
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 @@
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 @@
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')
diff --git a/src/version.c b/src/version.c
index cdfadeb..86ab085 100644
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 4044,
+/**/
4043,
/**/
4042,
diff --git a/src/vim9script.c b/src/vim9script.c
index e5e2695..3ebeab3 100644
--- a/src/vim9script.c
+++ b/src/vim9script.c
@@ -374,6 +374,8 @@
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 @@
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 @@
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;