comparison src/eval.c @ 9104:2242a5766417 v7.4.1836

commit https://github.com/vim/vim/commit/1d429610bf9e99a6252be8abbc910d6667e4d1da Author: Bram Moolenaar <Bram@vim.org> Date: Tue May 24 15:44:17 2016 +0200 patch 7.4.1836 Problem: When using a partial on a dictionary it always gets bound to that dictionary. Solution: Make a difference between binding a function to a dictionary explicitly or automatically.
author Christian Brabandt <cb@256bit.org>
date Tue, 24 May 2016 15:45:06 +0200
parents ad9322b525e1
children d319453f62b3
comparison
equal deleted inserted replaced
9103:b94f1b29ed35 9104:2242a5766417
9067 9067
9068 *doesrange = FALSE; 9068 *doesrange = FALSE;
9069 9069
9070 if (partial != NULL) 9070 if (partial != NULL)
9071 { 9071 {
9072 if (partial->pt_dict != NULL) 9072 /* When the function has a partial with a dict and there is a dict
9073 { 9073 * argument, use the dict argument. That is backwards compatible.
9074 /* When the function has a partial with a dict and there is a dict 9074 * When the dict was bound explicitly use the one from the partial. */
9075 * argument, use the dict argument. That is backwards compatible. 9075 if (partial->pt_dict != NULL
9076 */ 9076 && (selfdict_in == NULL || !partial->pt_auto))
9077 if (selfdict_in == NULL) 9077 selfdict = partial->pt_dict;
9078 selfdict = partial->pt_dict;
9079 }
9080 if (error == ERROR_NONE && partial->pt_argc > 0) 9078 if (error == ERROR_NONE && partial->pt_argc > 0)
9081 { 9079 {
9082 for (argv_clear = 0; argv_clear < partial->pt_argc; ++argv_clear) 9080 for (argv_clear = 0; argv_clear < partial->pt_argc; ++argv_clear)
9083 copy_tv(&partial->pt_argv[argv_clear], &argv[argv_clear]); 9081 copy_tv(&partial->pt_argv[argv_clear], &argv[argv_clear]);
9084 for (i = 0; i < argcount_in; ++i) 9082 for (i = 0; i < argcount_in; ++i)
12328 12326
12329 /* For "function(dict.func, [], dict)" and "func" is a partial 12327 /* For "function(dict.func, [], dict)" and "func" is a partial
12330 * use "dict". That is backwards compatible. */ 12328 * use "dict". That is backwards compatible. */
12331 if (dict_idx > 0) 12329 if (dict_idx > 0)
12332 { 12330 {
12331 /* The dict is bound explicitly, pt_auto is FALSE. */
12333 pt->pt_dict = argvars[dict_idx].vval.v_dict; 12332 pt->pt_dict = argvars[dict_idx].vval.v_dict;
12334 ++pt->pt_dict->dv_refcount; 12333 ++pt->pt_dict->dv_refcount;
12335 } 12334 }
12336 else if (arg_pt != NULL) 12335 else if (arg_pt != NULL)
12337 { 12336 {
12337 /* If the dict was bound automatically the result is also
12338 * bound automatically. */
12338 pt->pt_dict = arg_pt->pt_dict; 12339 pt->pt_dict = arg_pt->pt_dict;
12340 pt->pt_auto = arg_pt->pt_auto;
12339 if (pt->pt_dict != NULL) 12341 if (pt->pt_dict != NULL)
12340 ++pt->pt_dict->dv_refcount; 12342 ++pt->pt_dict->dv_refcount;
12341 } 12343 }
12342 12344
12343 pt->pt_refcount = 1; 12345 pt->pt_refcount = 1;
22277 ret = FAIL; 22279 ret = FAIL;
22278 } 22280 }
22279 } 22281 }
22280 } 22282 }
22281 22283
22282 if ((rettv->v_type == VAR_FUNC || rettv->v_type == VAR_PARTIAL) 22284 /* Turn "dict.Func" into a partial for "Func" bound to "dict".
22283 && selfdict != NULL) 22285 * Don't do this when "Func" is already a partial that was bound
22286 * explicitly (pt_auto is FALSE). */
22287 if (selfdict != NULL
22288 && (rettv->v_type == VAR_FUNC
22289 || (rettv->v_type == VAR_PARTIAL
22290 && (rettv->vval.v_partial->pt_auto
22291 || rettv->vval.v_partial->pt_dict == NULL))))
22284 { 22292 {
22285 char_u *fname = rettv->v_type == VAR_FUNC ? rettv->vval.v_string 22293 char_u *fname = rettv->v_type == VAR_FUNC ? rettv->vval.v_string
22286 : rettv->vval.v_partial->pt_name; 22294 : rettv->vval.v_partial->pt_name;
22287 char_u *tofree = NULL; 22295 char_u *tofree = NULL;
22288 ufunc_T *fp; 22296 ufunc_T *fp;
22292 /* Translate "s:func" to the stored function name. */ 22300 /* Translate "s:func" to the stored function name. */
22293 fname = fname_trans_sid(fname, fname_buf, &tofree, &error); 22301 fname = fname_trans_sid(fname, fname_buf, &tofree, &error);
22294 fp = find_func(fname); 22302 fp = find_func(fname);
22295 vim_free(tofree); 22303 vim_free(tofree);
22296 22304
22297 /* Turn "dict.Func" into a partial for "Func" with "dict". */
22298 if (fp != NULL && (fp->uf_flags & FC_DICT)) 22305 if (fp != NULL && (fp->uf_flags & FC_DICT))
22299 { 22306 {
22300 partial_T *pt = (partial_T *)alloc_clear(sizeof(partial_T)); 22307 partial_T *pt = (partial_T *)alloc_clear(sizeof(partial_T));
22301 22308
22302 if (pt != NULL) 22309 if (pt != NULL)
22303 { 22310 {
22304 pt->pt_refcount = 1; 22311 pt->pt_refcount = 1;
22305 pt->pt_dict = selfdict; 22312 pt->pt_dict = selfdict;
22313 pt->pt_auto = TRUE;
22306 selfdict = NULL; 22314 selfdict = NULL;
22307 if (rettv->v_type == VAR_FUNC) 22315 if (rettv->v_type == VAR_FUNC)
22308 { 22316 {
22309 /* Just a function: Take over the function name and use 22317 /* Just a function: Take over the function name and use
22310 * selfdict. */ 22318 * selfdict. */