Mercurial > vim
changeset 21699:1b96535705a0 v8.2.1399
patch 8.2.1399: Vim9: may find imported item in wrong script
Commit: https://github.com/vim/vim/commit/efa94447e85eacce62c1fcf6b63e7f3431e2cb1b
Author: Bram Moolenaar <Bram@vim.org>
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)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 08 Aug 2020 22:30:03 +0200 |
parents | df2188073dca |
children | a5743521c118 |
files | src/proto/vim9compile.pro src/testdir/test_vim9_script.vim src/userfunc.c src/version.c src/vim9compile.c |
diffstat | 5 files changed, 45 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- 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);
--- 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 <C-B> :call <sid>Funcx()<cr> + END + writefile(lines, 'Xmapscript.vim') + + source Xmapscript.vim + feedkeys("\<c-b>", "xt") + assert_equal(42, g:result) + + unlet g:result + delete('XsomeExport.vim') + delete('Xmapscript.vim') + nunmap <C-B> +enddef + def Test_vim9script_fails() CheckScriptFailure(['scriptversion 2', 'vim9script'], 'E1039:') CheckScriptFailure(['vim9script', 'scriptversion 2'], 'E1040:')
--- 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 <SNR>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);
--- 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,
--- 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;