@@ -867,7 +867,7 @@ static int valid_varname(char_u *varname);
867867static int tv_check_lock(int lock, char_u *name, int use_gettext);
868868static int item_copy(typval_T *from, typval_T *to, int deep, int copyID);
869869static char_u *find_option_end(char_u **arg, int *opt_flags);
870- static char_u *trans_function_name(char_u **pp, int skip, int flags, funcdict_T *fd);
870+ static char_u *trans_function_name(char_u **pp, int skip, int flags, funcdict_T *fd, partial_T **partial );
871871static int eval_fname_script(char_u *p);
872872static int eval_fname_sid(char_u *p);
873873static void list_func_head(ufunc_T *fp, int indent);
@@ -3476,7 +3476,7 @@ ex_call(exarg_T *eap)
34763476 return;
34773477 }
34783478
3479- tofree = trans_function_name(&arg, eap->skip, TFN_INT, &fudi);
3479+ tofree = trans_function_name(&arg, eap->skip, TFN_INT, &fudi, &partial );
34803480 if (fudi.fd_newkey != NULL)
34813481 {
34823482 /* Still need to give an error message for missing key. */
@@ -3491,9 +3491,18 @@ ex_call(exarg_T *eap)
34913491 if (fudi.fd_dict != NULL)
34923492 ++fudi.fd_dict->dv_refcount;
34933493
3494- /* If it is the name of a variable of type VAR_FUNC use its contents. */
3494+ /* If it is the name of a variable of type VAR_FUNC or VAR_PARTIAL use its
3495+ * contents. For VAR_PARTIAL get its partial, unless we already have one
3496+ * from trans_function_name(). */
34953497 len = (int)STRLEN(tofree);
3496- name = deref_func_name(tofree, &len, &partial, FALSE);
3498+ name = deref_func_name(tofree, &len,
3499+ partial != NULL ? NULL : &partial, FALSE);
3500+
3501+ /* When calling fdict.func(), where "func" is a partial, use "fdict"
3502+ * instead of the dict in the partial, for backwards compatibility.
3503+ * TODO: Do use the arguments in the partial? */
3504+ if (fudi.fd_dict != NULL)
3505+ partial = NULL;
34973506
34983507 /* Skip white space to allow ":call func ()". Not good, but required for
34993508 * backward compatibility. */
@@ -8561,15 +8570,17 @@ find_internal_func(
85618570/*
85628571 * Check if "name" is a variable of type VAR_FUNC. If so, return the function
85638572 * name it contains, otherwise return "name".
8564- * If "name" is of type VAR_PARTIAL also return "partial"
8573+ * If "partialp" is not NULL, and "name" is of type VAR_PARTIAL also set
8574+ * "partialp".
85658575 */
85668576 static char_u *
8567- deref_func_name(char_u *name, int *lenp, partial_T **partial , int no_autoload)
8577+ deref_func_name(char_u *name, int *lenp, partial_T **partialp , int no_autoload)
85688578{
85698579 dictitem_T *v;
85708580 int cc;
85718581
8572- *partial = NULL;
8582+ if (partialp != NULL)
8583+ *partialp = NULL;
85738584
85748585 cc = name[*lenp];
85758586 name[*lenp] = NUL;
@@ -8588,14 +8599,17 @@ deref_func_name(char_u *name, int *lenp, partial_T **partial, int no_autoload)
85888599
85898600 if (v != NULL && v->di_tv.v_type == VAR_PARTIAL)
85908601 {
8591- *partial = v->di_tv.vval.v_partial;
8592- if (*partial == NULL)
8602+ partial_T *pt = v->di_tv.vval.v_partial;
8603+
8604+ if (pt == NULL)
85938605 {
85948606 *lenp = 0;
85958607 return (char_u *)""; /* just in case */
85968608 }
8597- *lenp = (int)STRLEN((*partial)->pt_name);
8598- return (*partial)->pt_name;
8609+ if (partialp != NULL)
8610+ *partialp = pt;
8611+ *lenp = (int)STRLEN(pt->pt_name);
8612+ return pt->pt_name;
85998613 }
86008614
86018615 return name;
@@ -21700,18 +21714,23 @@ handle_subscript(
2170021714
2170121715 if (rettv->v_type == VAR_FUNC && selfdict != NULL)
2170221716 {
21703- partial_T *pt = (partial_T *)alloc_clear(sizeof(partial_T) );
21717+ ufunc_T *fp = find_func(rettv->vval.v_string );
2170421718
2170521719 /* Turn "dict.Func" into a partial for "Func" with "dict". */
21706- if (pt != NULL)
21720+ if (fp != NULL && (fp->uf_flags & FC_DICT) )
2170721721 {
21708- pt->pt_refcount = 1;
21709- pt->pt_dict = selfdict;
21710- selfdict = NULL;
21711- pt->pt_name = rettv->vval.v_string;
21712- func_ref(pt->pt_name);
21713- rettv->v_type = VAR_PARTIAL;
21714- rettv->vval.v_partial = pt;
21722+ partial_T *pt = (partial_T *)alloc_clear(sizeof(partial_T));
21723+
21724+ if (pt != NULL)
21725+ {
21726+ pt->pt_refcount = 1;
21727+ pt->pt_dict = selfdict;
21728+ selfdict = NULL;
21729+ pt->pt_name = rettv->vval.v_string;
21730+ func_ref(pt->pt_name);
21731+ rettv->v_type = VAR_PARTIAL;
21732+ rettv->vval.v_partial = pt;
21733+ }
2171521734 }
2171621735 }
2171721736
@@ -23220,7 +23239,7 @@ ex_function(exarg_T *eap)
2322023239 * g:func global function name, same as "func"
2322123240 */
2322223241 p = eap->arg;
23223- name = trans_function_name(&p, eap->skip, 0, &fudi);
23242+ name = trans_function_name(&p, eap->skip, 0, &fudi, NULL );
2322423243 paren = (vim_strchr(p, '(') != NULL);
2322523244 if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip)
2322623245 {
@@ -23533,7 +23552,7 @@ ex_function(exarg_T *eap)
2353323552 if (*p == '!')
2353423553 p = skipwhite(p + 1);
2353523554 p += eval_fname_script(p);
23536- vim_free(trans_function_name(&p, TRUE, 0, NULL));
23555+ vim_free(trans_function_name(&p, TRUE, 0, NULL, NULL ));
2353723556 if (*skipwhite(p) == '(')
2353823557 {
2353923558 ++nesting;
@@ -23788,7 +23807,8 @@ trans_function_name(
2378823807 char_u **pp,
2378923808 int skip, /* only find the end, don't evaluate */
2379023809 int flags,
23791- funcdict_T *fdp) /* return: info about dictionary used */
23810+ funcdict_T *fdp, /* return: info about dictionary used */
23811+ partial_T **partial) /* return: partial of a FuncRef */
2379223812{
2379323813 char_u *name = NULL;
2379423814 char_u *start;
@@ -23797,7 +23817,6 @@ trans_function_name(
2379723817 char_u sid_buf[20];
2379823818 int len;
2379923819 lval_T lv;
23800- partial_T *partial;
2380123820
2380223821 if (fdp != NULL)
2380323822 vim_memset(fdp, 0, sizeof(funcdict_T));
@@ -23882,15 +23901,15 @@ trans_function_name(
2388223901 if (lv.ll_exp_name != NULL)
2388323902 {
2388423903 len = (int)STRLEN(lv.ll_exp_name);
23885- name = deref_func_name(lv.ll_exp_name, &len, & partial,
23904+ name = deref_func_name(lv.ll_exp_name, &len, partial,
2388623905 flags & TFN_NO_AUTOLOAD);
2388723906 if (name == lv.ll_exp_name)
2388823907 name = NULL;
2388923908 }
2389023909 else
2389123910 {
2389223911 len = (int)(end - *pp);
23893- name = deref_func_name(*pp, &len, & partial, flags & TFN_NO_AUTOLOAD);
23912+ name = deref_func_name(*pp, &len, partial, flags & TFN_NO_AUTOLOAD);
2389423913 if (name == *pp)
2389523914 name = NULL;
2389623915 }
@@ -24115,7 +24134,7 @@ function_exists(char_u *name)
2411524134 int n = FALSE;
2411624135
2411724136 p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET|TFN_NO_AUTOLOAD,
24118- NULL);
24137+ NULL, NULL );
2411924138 nm = skipwhite(nm);
2412024139
2412124140 /* Only accept "funcname", "funcname ", "funcname (..." and
@@ -24132,7 +24151,7 @@ get_expanded_name(char_u *name, int check)
2413224151 char_u *nm = name;
2413324152 char_u *p;
2413424153
24135- p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET, NULL);
24154+ p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET, NULL, NULL );
2413624155
2413724156 if (p != NULL && *nm == NUL)
2413824157 if (!check || translated_function_exists(p))
@@ -24488,7 +24507,7 @@ ex_delfunction(exarg_T *eap)
2448824507 funcdict_T fudi;
2448924508
2449024509 p = eap->arg;
24491- name = trans_function_name(&p, eap->skip, 0, &fudi);
24510+ name = trans_function_name(&p, eap->skip, 0, &fudi, NULL );
2449224511 vim_free(fudi.fd_newkey);
2449324512 if (name == NULL)
2449424513 {
0 commit comments