# HG changeset patch # User Bram Moolenaar # Date 1641662102 -3600 # Node ID c8809b8d19de50bb299093670feb28de6b235c55 # Parent 07308e9dd7dc5abb6ff87c62e13cde90c0951225 patch 8.2.4044: Vim9: no error when importing the same script twice Commit: https://github.com/vim/vim/commit/7c24dfddc28776eeff7464982ae5b94e187b6135 Author: Bram Moolenaar 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. diff --git a/src/errors.h b/src/errors.h --- 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")); diff --git a/src/testdir/test_vim9_import.vim b/src/testdir/test_vim9_import.vim --- 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') diff --git a/src/version.c b/src/version.c --- 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, diff --git a/src/vim9script.c b/src/vim9script.c --- 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;