forked from aniani/vim
patch 8.2.4429: using script-local function from the wrong script
Problem: Using script-local function from the wrong script when using a partial. (Yegappan Lakshmanan) Solution: Include the script ID in the partial name.
This commit is contained in:
parent
0f6e28f686
commit
c2f17f7e64
@ -570,7 +570,7 @@ arg_map_func(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
|
||||
|| context->arg_types[0].type_curr->tt_type == VAR_BLOB
|
||||
|| context->arg_types[0].type_curr->tt_type == VAR_LIST)
|
||||
args[0] = &t_number;
|
||||
else if (context->arg_types[0].type_curr->tt_type == VAR_DICT)
|
||||
else if (context->arg_types[0].type_decl->tt_type == VAR_DICT)
|
||||
args[0] = &t_string;
|
||||
if (args[0] != NULL)
|
||||
args[1] = expected_ret;
|
||||
@ -4366,6 +4366,8 @@ common_function(typval_T *argvars, typval_T *rettv, int is_funcref)
|
||||
// would also work, but some plugins depend on the name being
|
||||
// printable text.
|
||||
name = get_scriptlocal_funcname(s);
|
||||
else if (trans_name != NULL && *trans_name == K_SPECIAL)
|
||||
name = alloc_printable_func_name(trans_name);
|
||||
else
|
||||
name = vim_strsave(s);
|
||||
|
||||
|
@ -38,6 +38,7 @@ char_u *printable_func_name(ufunc_T *fp);
|
||||
char_u *trans_function_name(char_u **pp, int *is_global, int skip, int flags, funcdict_T *fdp, partial_T **partial, type_T **type);
|
||||
char_u *untrans_function_name(char_u *name);
|
||||
char_u *get_scriptlocal_funcname(char_u *funcname);
|
||||
char_u *alloc_printable_func_name(char_u *fname);
|
||||
char_u *save_function_name(char_u **name, int *is_global, int skip, int flags, funcdict_T *fudi);
|
||||
void list_functions(regmatch_T *regmatch);
|
||||
ufunc_T *define_function(exarg_T *eap, char_u *name_arg, garray_T *lines_to_free);
|
||||
|
@ -423,6 +423,46 @@ def Test_import_funcref()
|
||||
delete('Xlib.vim')
|
||||
enddef
|
||||
|
||||
def Test_import_duplicate_function()
|
||||
# Function Hover() exists in both scripts, partial should refer to the right
|
||||
# one.
|
||||
var lines =<< trim END
|
||||
vim9script
|
||||
|
||||
def Hover(d: dict<any>): string
|
||||
return 'found it'
|
||||
enddef
|
||||
|
||||
export def NewLspServer(): dict<any>
|
||||
var d: dict<any> = {}
|
||||
d->extend({hover: function('Hover', [d])})
|
||||
return d
|
||||
enddef
|
||||
|
||||
NewLspServer()
|
||||
END
|
||||
writefile(lines, 'Xserver.vim')
|
||||
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
|
||||
import './Xserver.vim' as server
|
||||
|
||||
export def Hover()
|
||||
enddef
|
||||
|
||||
def AddServer()
|
||||
var d: dict<any> = server.NewLspServer()
|
||||
assert_equal('found it', d.hover())
|
||||
enddef
|
||||
AddServer()
|
||||
END
|
||||
v9.CheckScriptSuccess(lines)
|
||||
|
||||
delete('Xserver.vim')
|
||||
enddef
|
||||
|
||||
|
||||
def Test_import_fails()
|
||||
writefile([], 'Xfoo.vim')
|
||||
var lines =<< trim END
|
||||
|
@ -1958,17 +1958,29 @@ find_func_even_dead(char_u *name, int flags)
|
||||
|
||||
if ((flags & FFED_IS_GLOBAL) == 0)
|
||||
{
|
||||
int find_script_local = in_vim9script() && eval_isnamec1(*name)
|
||||
&& (name[1] != ':' || *name == 's');
|
||||
|
||||
if (find_script_local)
|
||||
// Find script-local function before global one.
|
||||
if (in_vim9script() && eval_isnamec1(*name)
|
||||
&& (name[1] != ':' || *name == 's'))
|
||||
{
|
||||
// Find script-local function before global one.
|
||||
func = find_func_with_sid(name[0] == 's' && name[1] == ':'
|
||||
? name + 2 : name, current_sctx.sc_sid);
|
||||
if (func != NULL)
|
||||
return func;
|
||||
}
|
||||
if (in_vim9script() && STRNCMP(name, "<SNR>", 5) == 0)
|
||||
{
|
||||
char_u *p = name + 5;
|
||||
long sid;
|
||||
|
||||
// printable "<SNR>123_Name" form
|
||||
sid = getdigits(&p);
|
||||
if (*p == '_')
|
||||
{
|
||||
func = find_func_with_sid(p + 1, (int)sid);
|
||||
if (func != NULL)
|
||||
return func;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((flags & FFED_NO_GLOBAL) == 0)
|
||||
@ -4067,6 +4079,23 @@ get_scriptlocal_funcname(char_u *funcname)
|
||||
return newname;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return script-local "fname" with the 3-byte sequence replaced by
|
||||
* printable <SNR> in allocated memory.
|
||||
*/
|
||||
char_u *
|
||||
alloc_printable_func_name(char_u *fname)
|
||||
{
|
||||
char_u *n = alloc(STRLEN(fname + 3) + 6);
|
||||
|
||||
if (n != NULL)
|
||||
{
|
||||
STRCPY(n, "<SNR>");
|
||||
STRCPY(n + 5, fname + 3);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
/*
|
||||
* Call trans_function_name(), except that a lambda is returned as-is.
|
||||
* Returns the name in allocated memory.
|
||||
|
@ -750,6 +750,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
4429,
|
||||
/**/
|
||||
4428,
|
||||
/**/
|
||||
|
@ -457,7 +457,7 @@ typval2type_int(typval_T *tv, int copyID, garray_T *type_gap, int flags)
|
||||
{
|
||||
type->tt_argcount -= tv->vval.v_partial->pt_argc;
|
||||
type->tt_min_argcount -= tv->vval.v_partial->pt_argc;
|
||||
if (type->tt_argcount == 0)
|
||||
if (type->tt_argcount <= 0)
|
||||
type->tt_args = NULL;
|
||||
else
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user