changeset 28261:20f6b0cdf38c v8.2.4656

patch 8.2.4656: Vim9: can't use item from "import autoload" with autoload dir Commit: https://github.com/vim/vim/commit/ccbfd4883f0385a1d84cc87785ddcc86185b4ad9 Author: Bram Moolenaar <Bram@vim.org> Date: Thu Mar 31 16:18:23 2022 +0100 patch 8.2.4656: Vim9: can't use item from "import autoload" with autoload dir Problem: Vim9: can't use items from "import autoload" with autoload directory name. Solution: Let sn_autoload_prefix overrule sn_import_autoload. (closes #10054)
author Bram Moolenaar <Bram@vim.org>
date Thu, 31 Mar 2022 17:30:03 +0200
parents 21f8175f4d9f
children 59a7125e87f4
files src/structs.h src/testdir/test_vim9_import.vim src/version.c src/vim9expr.c src/vim9instr.c src/vim9script.c
diffstat 6 files changed, 64 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/src/structs.h
+++ b/src/structs.h
@@ -1868,6 +1868,7 @@ typedef struct
     char_u	*sn_autoload_prefix;
 
     // TRUE for a script used with "import autoload './dirname/script.vim'"
+    // For "../autoload/script.vim" sn_autoload_prefix is also set.
     int		sn_import_autoload;
 
 # ifdef FEAT_PROFILE
--- a/src/testdir/test_vim9_import.vim
+++ b/src/testdir/test_vim9_import.vim
@@ -969,6 +969,31 @@ def Test_autoload_import_relative()
   delete('XimportRel3.vim')
 enddef
 
+def Test_autoload_import_relative_autoload_dir()
+  mkdir('autoload', 'p')
+  var lines =<< trim END
+      vim9script
+      export def Bar()
+        g:called_bar = 'yes'
+      enddef
+  END
+  writefile(lines, 'autoload/script.vim')
+
+  lines =<< trim END
+      vim9script
+      import autoload './autoload/script.vim'
+      def Foo()
+        script.Bar()
+      enddef
+      Foo()
+      assert_equal('yes', g:called_bar)
+  END
+  v9.CheckScriptSuccess(lines)
+
+  unlet g:called_bar
+  delete('autoload', 'rf')
+enddef
+
 func Test_import_in_diffexpr()
   CheckExecutable diff
 
--- 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 */
 /**/
+    4656,
+/**/
     4655,
 /**/
     4654,
--- a/src/vim9expr.c
+++ b/src/vim9expr.c
@@ -298,26 +298,31 @@ compile_load_scriptvar(
 	*p = NUL;
 
 	si = SCRIPT_ITEM(import->imp_sid);
-	if (si->sn_autoload_prefix != NULL
+	if (si->sn_import_autoload && si->sn_state == SN_STATE_NOT_LOADED)
+	    // "import autoload './dir/script.vim'" or
+	    // "import autoload './autoload/script.vim'" - load script first
+	    res = generate_SOURCE(cctx, import->imp_sid);
+
+	if (res == OK)
+	{
+	    if (si->sn_autoload_prefix != NULL
 					&& si->sn_state == SN_STATE_NOT_LOADED)
-	{
-	    char_u  *auto_name = concat_str(si->sn_autoload_prefix, exp_name);
+	    {
+		char_u  *auto_name =
+				  concat_str(si->sn_autoload_prefix, exp_name);
 
-	    // autoload script must be loaded later, access by the autoload
-	    // name.  If a '(' follows it must be a function.  Otherwise we
-	    // don't know, it can be "script.Func".
-	    if (cc == '(' || paren_follows_after_expr)
-		res = generate_PUSHFUNC(cctx, auto_name, &t_func_any);
-	    else
-		res = generate_AUTOLOAD(cctx, auto_name, &t_any);
-	    vim_free(auto_name);
-	    done = TRUE;
-	}
-	else if (si->sn_import_autoload && si->sn_state == SN_STATE_NOT_LOADED)
-	{
-	    // "import autoload './dir/script.vim'" - load script first
-	    res = generate_SOURCE(cctx, import->imp_sid);
-	    if (res == OK)
+		// autoload script must be loaded later, access by the autoload
+		// name.  If a '(' follows it must be a function.  Otherwise we
+		// don't know, it can be "script.Func".
+		if (cc == '(' || paren_follows_after_expr)
+		    res = generate_PUSHFUNC(cctx, auto_name, &t_func_any);
+		else
+		    res = generate_AUTOLOAD(cctx, auto_name, &t_any);
+		vim_free(auto_name);
+		done = TRUE;
+	    }
+	    else if (si->sn_import_autoload
+					&& si->sn_state == SN_STATE_NOT_LOADED)
 	    {
 		// If a '(' follows it must be a function.  Otherwise we don't
 		// know, it can be "script.Func".
@@ -331,14 +336,15 @@ compile_load_scriptvar(
 		else
 		    res = generate_OLDSCRIPT(cctx, ISN_LOADEXPORT, exp_name,
 						      import->imp_sid, &t_any);
+		done = TRUE;
 	    }
-	    done = TRUE;
+	    else
+	    {
+		idx = find_exported(import->imp_sid, exp_name, &ufunc, &type,
+							     cctx, NULL, TRUE);
+	    }
 	}
-	else
-	{
-	    idx = find_exported(import->imp_sid, exp_name, &ufunc, &type,
-							    cctx, NULL, TRUE);
-	}
+
 	*p = cc;
 	*end = p;
 	if (done)
--- a/src/vim9instr.c
+++ b/src/vim9instr.c
@@ -1932,7 +1932,9 @@ generate_store_var(
 		isntype_T isn_type = ISN_STORES;
 
 		if (SCRIPT_ID_VALID(scriptvar_sid)
-			 && SCRIPT_ITEM(scriptvar_sid)->sn_import_autoload)
+			 && SCRIPT_ITEM(scriptvar_sid)->sn_import_autoload
+			 && SCRIPT_ITEM(scriptvar_sid)->sn_autoload_prefix
+								       == NULL)
 		{
 		    // "import autoload './dir/script.vim'" - load script first
 		    if (generate_SOURCE(cctx, scriptvar_sid) == FAIL)
--- a/src/vim9script.c
+++ b/src/vim9script.c
@@ -415,6 +415,9 @@ handle_import_fname(char_u *fname, int i
 	si = SCRIPT_ITEM(*sid);
 	si->sn_import_autoload = TRUE;
 
+	if (si->sn_autoload_prefix == NULL)
+	    si->sn_autoload_prefix = get_autoload_prefix(si);
+
 	// with testing override: load autoload script right away
 	if (!override_autoload || si->sn_state != SN_STATE_NOT_LOADED)
 	    return OK;