]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 8.2.0960: cannot use :import in legacy Vim script v8.2.0960
authorBram Moolenaar <Bram@vim.org>
Thu, 11 Jun 2020 21:10:46 +0000 (23:10 +0200)
committerBram Moolenaar <Bram@vim.org>
Thu, 11 Jun 2020 21:10:46 +0000 (23:10 +0200)
Problem:    Cannot use :import in legacy Vim script.
Solution:   Support :import in any Vim script.

src/evalvars.c
src/testdir/test_vim9_script.vim
src/userfunc.c
src/version.c
src/vim9script.c

index 8b3ce2e9035267a941d213bb79db10d30b63ee4a..3d03ed8f1b95946d74ed82565820e97a4533896a 100644 (file)
@@ -2359,9 +2359,13 @@ get_var_tv(
            *dip = v;
     }
 
-    if (tv == NULL && current_sctx.sc_version == SCRIPT_VERSION_VIM9)
+    if (tv == NULL && (current_sctx.sc_version == SCRIPT_VERSION_VIM9
+                                              || STRNCMP(name, "s:", 2) == 0))
     {
-       imported_T *import = find_imported(name, 0, NULL);
+       imported_T  *import;
+       char_u      *p = STRNCMP(name, "s:", 2) == 0 ? name + 2 : name;
+
+       import = find_imported(p, 0, NULL);
 
        // imported variable from another script
        if (import != NULL)
index 1092ff9f2649cd3e6fb2a0d591e8710a9050a658..e9303f1d852d7a42f53098435595ebfcf5313146 100644 (file)
@@ -736,7 +736,7 @@ def Test_vim9script_fails()
   CheckScriptFailure(['scriptversion 2', 'vim9script'], 'E1039:')
   CheckScriptFailure(['vim9script', 'scriptversion 2'], 'E1040:')
   CheckScriptFailure(['export let some = 123'], 'E1042:')
-  CheckScriptFailure(['import some from "./Xexport.vim"'], 'E1042:')
+  CheckScriptFailure(['import some from "./Xexport.vim"'], 'E1048:')
   CheckScriptFailure(['vim9script', 'export let g:some'], 'E1044:')
   CheckScriptFailure(['vim9script', 'export echo 134'], 'E1043:')
 
@@ -1836,6 +1836,47 @@ def Test_forward_declaration()
   delete('Xforward')
 enddef
 
+def Test_source_vim9_from_legacy()
+  let legacy_lines =<< trim END
+    source Xvim9_script.vim
+
+    call assert_false(exists('local'))
+    call assert_false(exists('exported'))
+    call assert_false(exists('s:exported'))
+    call assert_equal('global', global)
+    call assert_equal('global', g:global)
+
+    " imported variable becomes script-local
+    import exported from './Xvim9_script.vim'
+    call assert_equal('exported', s:exported)
+    call assert_false(exists('exported'))
+
+    " imported function becomes script-local
+    import GetText from './Xvim9_script.vim'
+    call assert_equal('text', s:GetText())
+    call assert_false(exists('*GetText'))
+  END
+  writefile(legacy_lines, 'Xlegacy_script.vim')
+
+  let vim9_lines =<< trim END
+    vim9script
+    let local = 'local'
+    g:global = 'global'
+    export let exported = 'exported'
+    export def GetText(): string
+       return 'text'
+    enddef
+  END
+  writefile(vim9_lines, 'Xvim9_script.vim')
+
+  source Xlegacy_script.vim
+
+  assert_equal('global', g:global)
+"  unlet g:global
+
+  delete('Xlegacy_script.vim')
+  delete('Xvim9_script.vim')
+enddef
 
 " Keep this last, it messes up highlighting.
 def Test_substitute_cmd()
index b495769a95bd0055e8e12a25277893a9bd4e508d..e2658fe596c8198c07129b4cf2ed92d0f05c98b6 100644 (file)
@@ -719,20 +719,45 @@ find_func_even_dead(char_u *name, int is_global, cctx_T *cctx)
     ufunc_T    *func;
     imported_T *imported;
 
-    if (in_vim9script() && !is_global)
+    if (!is_global)
     {
-       // Find script-local function before global one.
-       func = find_func_with_sid(name, current_sctx.sc_sid);
-       if (func != NULL)
-           return func;
-
-       // Find imported funcion before global one.
-       imported = find_imported(name, 0, cctx);
-       if (imported != NULL && imported->imp_funcname != NULL)
+       char_u *after_script = NULL;
+
+       if (in_vim9script())
        {
-           hi = hash_find(&func_hashtab, imported->imp_funcname);
-           if (!HASHITEM_EMPTY(hi))
-               return HI2UF(hi);
+           // Find script-local function before global one.
+           func = find_func_with_sid(name, current_sctx.sc_sid);
+           if (func != NULL)
+               return func;
+       }
+
+       if (!in_vim9script()
+               && name[0] == K_SPECIAL
+               && name[1] == KS_EXTRA
+               && name[2] == KE_SNR)
+       {
+           long sid;
+
+           // Caller changes s: to <SNR>99_name.
+
+           after_script = name + 3;
+           sid = getdigits(&after_script);
+           if (sid == current_sctx.sc_sid && *after_script == '_')
+               ++after_script;
+           else
+               after_script = NULL;
+       }
+       if (in_vim9script() || after_script != NULL)
+       {
+           // Find imported function before global one.
+           imported = find_imported(
+                         after_script == NULL ? name : after_script, 0, cctx);
+           if (imported != NULL && imported->imp_funcname != NULL)
+           {
+               hi = hash_find(&func_hashtab, imported->imp_funcname);
+               if (!HASHITEM_EMPTY(hi))
+                   return HI2UF(hi);
+           }
        }
     }
 
index 1479c2ab60eacdaf6236c9f549b9b002d6c775e5..d6976c50026acb23588b43e517ed0f362a3eb942 100644 (file)
@@ -754,6 +754,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    960,
 /**/
     959,
 /**/
index fa0f8c67329dd8610df195c5831608cdb01cfd36..ca1470269341447dfb77640e02ae91c695d0907d 100644 (file)
@@ -17,7 +17,7 @@
 
 #include "vim9.h"
 
-static char e_needs_vim9[] = N_("E1042: import/export can only be used in vim9script");
+static char e_needs_vim9[] = N_("E1042: export can only be used in vim9script");
 
     int
 in_vim9script(void)
@@ -141,16 +141,10 @@ free_imports(int sid)
     void
 ex_import(exarg_T *eap)
 {
-    if (current_sctx.sc_version != SCRIPT_VERSION_VIM9)
-       emsg(_(e_needs_vim9));
-    else
-    {
-       char_u *cmd_end = handle_import(eap->arg, NULL,
-                                                   current_sctx.sc_sid, NULL);
+    char_u *cmd_end = handle_import(eap->arg, NULL, current_sctx.sc_sid, NULL);
 
-       if (cmd_end != NULL)
-           eap->nextcmd = check_nextcmd(cmd_end);
-    }
+    if (cmd_end != NULL)
+       eap->nextcmd = check_nextcmd(cmd_end);
 }
 
 /*