From 9721fb4ea3db2559aaf7f71458da8ddda30ff93e Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Thu, 11 Jun 2020 23:10:46 +0200 Subject: patch 8.2.0960: cannot use :import in legacy Vim script Problem: Cannot use :import in legacy Vim script. Solution: Support :import in any Vim script. --- src/evalvars.c | 8 +++++-- src/testdir/test_vim9_script.vim | 43 ++++++++++++++++++++++++++++++++++- src/userfunc.c | 49 ++++++++++++++++++++++++++++++---------- src/version.c | 2 ++ src/vim9script.c | 14 ++++-------- 5 files changed, 91 insertions(+), 25 deletions(-) diff --git a/src/evalvars.c b/src/evalvars.c index 8b3ce2e90..3d03ed8f1 100644 --- a/src/evalvars.c +++ b/src/evalvars.c @@ -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) diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim index 1092ff9f2..e9303f1d8 100644 --- a/src/testdir/test_vim9_script.vim +++ b/src/testdir/test_vim9_script.vim @@ -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() diff --git a/src/userfunc.c b/src/userfunc.c index b495769a9..e2658fe59 100644 --- a/src/userfunc.c +++ b/src/userfunc.c @@ -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 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); + } } } diff --git a/src/version.c b/src/version.c index 1479c2ab6..d6976c500 100644 --- a/src/version.c +++ b/src/version.c @@ -754,6 +754,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 960, /**/ 959, /**/ diff --git a/src/vim9script.c b/src/vim9script.c index fa0f8c673..ca1470269 100644 --- a/src/vim9script.c +++ b/src/vim9script.c @@ -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); } /* -- cgit v1.2.1