@@ -110,6 +110,7 @@ static char *e_illvar = N_("E461: Illegal variable name: %s");
110110#ifdef FEAT_FLOAT
111111static char *e_float_as_string = N_("E806: using Float as a String");
112112#endif
113+ static char *e_dict_both = N_("E924: can't have both a \"self\" dict and a partial: %s");
113114
114115#define NAMESPACE_CHAR (char_u *)"abglstvw"
115116
@@ -8912,8 +8913,7 @@ call_func(
89128913 name);
89138914 break;
89148915 case ERROR_BOTH:
8915- emsg_funcname(N_("E924: can't have both a \"self\" dict and a partial: %s"),
8916- name);
8916+ emsg_funcname(e_dict_both, name);
89178917 break;
89188918 }
89198919 }
@@ -11782,12 +11782,29 @@ f_function(typval_T *argvars, typval_T *rettv)
1178211782{
1178311783 char_u *s;
1178411784 char_u *name;
11785+ int use_string = FALSE;
1178511786
11786- s = get_tv_string(&argvars[0]);
11787- if (s == NULL || *s == NUL || VIM_ISDIGIT(*s))
11787+ if (argvars[0].v_type == VAR_FUNC)
11788+ {
11789+ /* function(MyFunc, [arg], dict) */
11790+ s = argvars[0].vval.v_string;
11791+ }
11792+ else if (argvars[0].v_type == VAR_PARTIAL
11793+ && argvars[0].vval.v_partial != NULL)
11794+ /* function(dict.MyFunc, [arg]) */
11795+ s = argvars[0].vval.v_partial->pt_name;
11796+ else
11797+ {
11798+ /* function('MyFunc', [arg], dict) */
11799+ s = get_tv_string(&argvars[0]);
11800+ use_string = TRUE;
11801+ }
11802+
11803+ if (s == NULL || *s == NUL || (use_string && VIM_ISDIGIT(*s)))
1178811804 EMSG2(_(e_invarg2), s);
1178911805 /* Don't check an autoload name for existence here. */
11790- else if (vim_strchr(s, AUTOLOAD_CHAR) == NULL && !function_exists(s))
11806+ else if (use_string && vim_strchr(s, AUTOLOAD_CHAR) == NULL
11807+ && !function_exists(s))
1179111808 EMSG2(_("E700: Unknown function: %s"), s);
1179211809 else
1179311810 {
@@ -11837,6 +11854,12 @@ f_function(typval_T *argvars, typval_T *rettv)
1183711854 vim_free(name);
1183811855 return;
1183911856 }
11857+ if (argvars[0].v_type == VAR_PARTIAL)
11858+ {
11859+ EMSG2(_(e_dict_both), name);
11860+ vim_free(name);
11861+ return;
11862+ }
1184011863 if (argvars[dict_idx].vval.v_dict == NULL)
1184111864 dict_idx = 0;
1184211865 }
@@ -11880,7 +11903,12 @@ f_function(typval_T *argvars, typval_T *rettv)
1188011903 }
1188111904 }
1188211905
11883- if (dict_idx > 0)
11906+ if (argvars[0].v_type == VAR_PARTIAL)
11907+ {
11908+ pt->pt_dict = argvars[0].vval.v_partial->pt_dict;
11909+ ++pt->pt_dict->dv_refcount;
11910+ }
11911+ else if (dict_idx > 0)
1188411912 {
1188511913 pt->pt_dict = argvars[dict_idx].vval.v_dict;
1188611914 ++pt->pt_dict->dv_refcount;
@@ -21533,7 +21561,7 @@ handle_subscript(
2153321561 rettv->v_type = VAR_UNKNOWN;
2153421562
2153521563 /* Invoke the function. Recursive! */
21536- if (rettv-> v_type == VAR_PARTIAL)
21564+ if (functv. v_type == VAR_PARTIAL)
2153721565 {
2153821566 pt = functv.vval.v_partial;
2153921567 s = pt->pt_name;
@@ -21582,6 +21610,23 @@ handle_subscript(
2158221610 }
2158321611 }
2158421612 }
21613+
21614+ if (rettv->v_type == VAR_FUNC && selfdict != NULL)
21615+ {
21616+ partial_T *pt = (partial_T *)alloc_clear(sizeof(partial_T));
21617+
21618+ /* Turn "dict.Func" into a partial for "Func" with "dict". */
21619+ if (pt != NULL)
21620+ {
21621+ pt->pt_dict = selfdict;
21622+ selfdict = NULL;
21623+ pt->pt_name = rettv->vval.v_string;
21624+ func_ref(pt->pt_name);
21625+ rettv->v_type = VAR_PARTIAL;
21626+ rettv->vval.v_partial = pt;
21627+ }
21628+ }
21629+
2158521630 dict_unref(selfdict);
2158621631 return ret;
2158721632}
0 commit comments