To: vim_dev@googlegroups.com Subject: Patch 7.4.1589 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.4.1589 Problem: Combining dict and args with partial doesn't always work. Solution: Use the arguments from the partial. Files: src/eval.c, src/testdir/test_partial.vim *** ../vim-7.4.1588/src/eval.c 2016-03-17 21:11:48.392657218 +0100 --- src/eval.c 2016-03-17 23:05:26.715794142 +0100 *************** *** 3461,3467 **** int doesrange; int failed = FALSE; funcdict_T fudi; ! partial_T *partial; if (eap->skip) { --- 3461,3467 ---- int doesrange; int failed = FALSE; funcdict_T fudi; ! partial_T *partial = NULL; if (eap->skip) { *************** *** 3497,3508 **** name = deref_func_name(tofree, &len, partial != NULL ? NULL : &partial, FALSE); - /* When calling fdict.func(), where "func" is a partial, use "fdict" - * instead of the dict in the partial, for backwards compatibility. - * TODO: Do use the arguments in the partial? */ - if (fudi.fd_dict != NULL) - partial = NULL; - /* Skip white space to allow ":call func ()". Not good, but required for * backward compatibility. */ startarg = skipwhite(arg); --- 3497,3502 ---- *************** *** 21734,21750 **** } } ! if (rettv->v_type == VAR_FUNC && selfdict != NULL) { ! char_u *fname; char_u *tofree = NULL; ufunc_T *fp; char_u fname_buf[FLEN_FIXED + 1]; int error; /* Translate "s:func" to the stored function name. */ ! fname = fname_trans_sid(rettv->vval.v_string, fname_buf, ! &tofree, &error); fp = find_func(fname); vim_free(tofree); --- 21728,21745 ---- } } ! if ((rettv->v_type == VAR_FUNC || rettv->v_type == VAR_PARTIAL) ! && selfdict != NULL) { ! char_u *fname = rettv->v_type == VAR_FUNC ? rettv->vval.v_string ! : rettv->vval.v_partial->pt_name; char_u *tofree = NULL; ufunc_T *fp; char_u fname_buf[FLEN_FIXED + 1]; int error; /* Translate "s:func" to the stored function name. */ ! fname = fname_trans_sid(fname, fname_buf, &tofree, &error); fp = find_func(fname); vim_free(tofree); *************** *** 21758,21764 **** pt->pt_refcount = 1; pt->pt_dict = selfdict; selfdict = NULL; ! pt->pt_name = rettv->vval.v_string; func_ref(pt->pt_name); rettv->v_type = VAR_PARTIAL; rettv->vval.v_partial = pt; --- 21753,21786 ---- pt->pt_refcount = 1; pt->pt_dict = selfdict; selfdict = NULL; ! if (rettv->v_type == VAR_FUNC) ! { ! /* just a function: use selfdict */ ! pt->pt_name = rettv->vval.v_string; ! } ! else ! { ! partial_T *ret_pt = rettv->vval.v_partial; ! int i; ! ! /* partial: use selfdict and copy args */ ! pt->pt_name = vim_strsave(ret_pt->pt_name); ! if (ret_pt->pt_argc > 0) ! { ! pt->pt_argv = (typval_T *)alloc( ! sizeof(typval_T) * ret_pt->pt_argc); ! if (pt->pt_argv == NULL) ! /* out of memory: drop the arguments */ ! pt->pt_argc = 0; ! else ! { ! pt->pt_argc = ret_pt->pt_argc; ! for (i = 0; i < pt->pt_argc; i++) ! copy_tv(&ret_pt->pt_argv[i], &pt->pt_argv[i]); ! } ! } ! partial_unref(ret_pt); ! } func_ref(pt->pt_name); rettv->v_type = VAR_PARTIAL; rettv->vval.v_partial = pt; *************** *** 23915,23920 **** --- 23937,23944 ---- { name = vim_strsave(lv.ll_tv->vval.v_partial->pt_name); *pp = end; + if (partial != NULL) + *partial = lv.ll_tv->vval.v_partial; } else { *** ../vim-7.4.1588/src/testdir/test_partial.vim 2016-03-17 21:11:48.392657218 +0100 --- src/testdir/test_partial.vim 2016-03-17 23:07:28.030494682 +0100 *************** *** 115,120 **** --- 115,150 ---- call assert_equal('bar', B()) endfunc + function! s:cache_arg(arg) dict + let s:result = self.name . '/' . a:arg + return s:result + endfunction + + func Test_script_function_in_dict_arg() + let s:obj = {'name': 'foo'} + let s:obj['clear'] = function('s:cache_arg') + + call assert_equal('foo/bar', s:obj.clear('bar')) + let F = s:obj.clear + let s:result = '' + call assert_equal('foo/bar', F('bar')) + call assert_equal('foo/bar', s:result) + + let s:obj['clear'] = function('s:cache_arg', ['bar']) + call assert_equal('foo/bar', s:obj.clear()) + let s:result = '' + call s:obj.clear() + call assert_equal('foo/bar', s:result) + + let F = s:obj.clear + call assert_equal('foo/bar', F()) + let s:result = '' + call F() + call assert_equal('foo/bar', s:result) + + call assert_equal('foo/bar', call(s:obj.clear, [], s:obj)) + endfunc + func Test_partial_exists() let F = function('MyFunc') call assert_true(exists('*F')) *** ../vim-7.4.1588/src/version.c 2016-03-17 22:06:49.933452325 +0100 --- src/version.c 2016-03-17 23:10:28.724559618 +0100 *************** *** 750,751 **** --- 750,753 ---- { /* Add new patch number below this line */ + /**/ + 1589, /**/ -- hundred-and-one symptoms of being an internet addict: 72. Somebody at IRC just mentioned a way to obtain full motion video without a PC using a wireless protocol called NTSC, you wonder how you never heard about it /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///