0
0
mirror of https://github.com/vim/vim.git synced 2025-09-23 03:43:49 -04:00

patch 7.4.2137

Problem:    Using function() with a name will find another function when it is
            redefined.
Solution:   Add funcref().  Refer to lambda using a partial.  Fix several
            reference counting issues.
This commit is contained in:
Bram Moolenaar
2016-08-01 15:40:54 +02:00
parent 5801644819
commit 437bafe4c8
16 changed files with 447 additions and 231 deletions

View File

@@ -5011,6 +5011,17 @@ get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate)
return OK;
}
/*
* Return the function name of the partial.
*/
char_u *
partial_name(partial_T *pt)
{
if (pt->pt_name != NULL)
return pt->pt_name;
return pt->pt_func->uf_name;
}
static void
partial_free(partial_T *pt)
{
@@ -5020,8 +5031,13 @@ partial_free(partial_T *pt)
clear_tv(&pt->pt_argv[i]);
vim_free(pt->pt_argv);
dict_unref(pt->pt_dict);
func_unref(pt->pt_name);
vim_free(pt->pt_name);
if (pt->pt_name != NULL)
{
func_unref(pt->pt_name);
vim_free(pt->pt_name);
}
else
func_ptr_unref(pt->pt_func);
vim_free(pt);
}
@@ -5051,11 +5067,11 @@ func_equal(
/* empty and NULL function name considered the same */
s1 = tv1->v_type == VAR_FUNC ? tv1->vval.v_string
: tv1->vval.v_partial->pt_name;
: partial_name(tv1->vval.v_partial);
if (s1 != NULL && *s1 == NUL)
s1 = NULL;
s2 = tv2->v_type == VAR_FUNC ? tv2->vval.v_string
: tv2->vval.v_partial->pt_name;
: partial_name(tv2->vval.v_partial);
if (s2 != NULL && *s2 == NUL)
s2 = NULL;
if (s1 == NULL || s2 == NULL)
@@ -5550,7 +5566,7 @@ set_ref_in_item(
}
else if (tv->v_type == VAR_FUNC)
{
abort = set_ref_in_func(tv->vval.v_string, copyID);
abort = set_ref_in_func(tv->vval.v_string, NULL, copyID);
}
else if (tv->v_type == VAR_PARTIAL)
{
@@ -5561,7 +5577,7 @@ set_ref_in_item(
*/
if (pt != NULL)
{
abort = set_ref_in_func(pt->pt_name, copyID);
abort = set_ref_in_func(pt->pt_name, pt->pt_func, copyID);
if (pt->pt_dict != NULL)
{
@@ -5735,7 +5751,7 @@ echo_string_core(
{
partial_T *pt = tv->vval.v_partial;
char_u *fname = string_quote(pt == NULL ? NULL
: pt->pt_name, FALSE);
: partial_name(pt), FALSE);
garray_T ga;
int i;
char_u *tf;
@@ -6871,7 +6887,7 @@ handle_subscript(
if (functv.v_type == VAR_PARTIAL)
{
pt = functv.vval.v_partial;
s = pt->pt_name;
s = partial_name(pt);
}
else
s = functv.vval.v_string;
@@ -10025,7 +10041,7 @@ filter_map_one(typval_T *tv, typval_T *expr, int map, int *remp)
{
partial_T *partial = expr->vval.v_partial;
s = partial->pt_name;
s = partial_name(partial);
if (call_func(s, (int)STRLEN(s), &rettv, 2, argv, NULL,
0L, 0L, &dummy, TRUE, partial, NULL) == FAIL)
goto theend;