Mercurial > vim
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. */ |