# HG changeset patch # User Bram Moolenaar # Date 1596918603 -7200 # Node ID 1b96535705a0811de413c93a755d2f6015ffcb2f # Parent df2188073dca7d5f3fa9531fbeec02651aaf33d4 patch 8.2.1399: Vim9: may find imported item in wrong script Commit: https://github.com/vim/vim/commit/efa94447e85eacce62c1fcf6b63e7f3431e2cb1b Author: Bram Moolenaar Date: Sat Aug 8 22:16:00 2020 +0200 patch 8.2.1399: Vim9: may find imported item in wrong script Problem: Vim9: may find imported item in wrong script. Solution: When looking up script-local function use the embedded script ID. (issue #6644) diff --git a/src/proto/vim9compile.pro b/src/proto/vim9compile.pro --- a/src/proto/vim9compile.pro +++ b/src/proto/vim9compile.pro @@ -12,6 +12,7 @@ char *vartype_name(vartype_T type); char *type_name(type_T *type, char **tofree); int get_script_item_idx(int sid, char_u *name, int check_writable); imported_T *find_imported(char_u *name, size_t len, cctx_T *cctx); +imported_T *find_imported_in_script(char_u *name, size_t len, int sid); int vim9_comment_start(char_u *p); char_u *peek_next_line_from_context(cctx_T *cctx); char_u *next_line_from_context(cctx_T *cctx, int skip_comment); diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim --- a/src/testdir/test_vim9_script.vim +++ b/src/testdir/test_vim9_script.vim @@ -1430,6 +1430,31 @@ def Test_import_in_filetype() &rtp = save_rtp enddef +def Test_use_import_in_mapping() + let lines =<< trim END + vim9script + export def Funcx() + g:result = 42 + enddef + END + writefile(lines, 'XsomeExport.vim') + lines =<< trim END + vim9script + import Funcx from './XsomeExport.vim' + nnoremap :call Funcx() + END + writefile(lines, 'Xmapscript.vim') + + source Xmapscript.vim + feedkeys("\", "xt") + assert_equal(42, g:result) + + unlet g:result + delete('XsomeExport.vim') + delete('Xmapscript.vim') + nunmap +enddef + def Test_vim9script_fails() CheckScriptFailure(['scriptversion 2', 'vim9script'], 'E1039:') CheckScriptFailure(['vim9script', 'scriptversion 2'], 'E1040:') diff --git a/src/userfunc.c b/src/userfunc.c --- a/src/userfunc.c +++ b/src/userfunc.c @@ -791,6 +791,7 @@ find_func_even_dead(char_u *name, int is { int vim9script = in_vim9script(); char_u *after_script = NULL; + long sid = 0; if (vim9script) { @@ -800,18 +801,15 @@ find_func_even_dead(char_u *name, int is return func; } - if (!vim9script - && name[0] == K_SPECIAL + if (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 == '_') + if (*after_script == '_') ++after_script; else after_script = NULL; @@ -819,8 +817,11 @@ find_func_even_dead(char_u *name, int is if (vim9script || after_script != NULL) { // Find imported function before global one. - imported = find_imported( - after_script == NULL ? name : after_script, 0, cctx); + if (after_script != NULL && sid != current_sctx.sc_sid) + imported = find_imported_in_script(after_script, 0, sid); + else + 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); diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -755,6 +755,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1399, +/**/ 1398, /**/ 1397, diff --git a/src/vim9compile.c b/src/vim9compile.c --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -2548,12 +2548,10 @@ get_script_item_idx(int sid, char_u *nam imported_T * find_imported(char_u *name, size_t len, cctx_T *cctx) { - scriptitem_T *si; int idx; if (current_sctx.sc_sid <= 0) return NULL; - si = SCRIPT_ITEM(current_sctx.sc_sid); if (cctx != NULL) for (idx = 0; idx < cctx->ctx_imports.ga_len; ++idx) { @@ -2566,6 +2564,15 @@ find_imported(char_u *name, size_t len, return import; } + return find_imported_in_script(name, len, current_sctx.sc_sid); +} + + imported_T * +find_imported_in_script(char_u *name, size_t len, int sid) +{ + scriptitem_T *si = SCRIPT_ITEM(sid); + int idx; + for (idx = 0; idx < si->sn_imports.ga_len; ++idx) { imported_T *import = ((imported_T *)si->sn_imports.ga_data) + idx;