aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Ennen <mike.ennen@gmail.com>2016-10-28 22:44:42 -0700
committerJames McCoy <jamessan@jamessan.com>2016-12-12 10:17:35 -0500
commitbae31b764a5607fad5d914f271e93e10c2d0bfbe (patch)
treee3af8d044005cd673f90ba33974675f92ef4347b
parent3213b28c01313c7f0e7e0e01f72a0fbfef85fa3e (diff)
downloadrneovim-bae31b764a5607fad5d914f271e93e10c2d0bfbe.tar.gz
rneovim-bae31b764a5607fad5d914f271e93e10c2d0bfbe.tar.bz2
rneovim-bae31b764a5607fad5d914f271e93e10c2d0bfbe.zip
vim-patch:7.4.1608
Problem: string() doesn't handle a partial. Solution: Make a string from a partial. https://github.com/vim/vim/commit/5c29154b521e9948190be653cfda666ecbb63b5b
-rw-r--r--src/nvim/eval/encode.c29
-rw-r--r--src/nvim/testdir/test_partial.vim86
-rw-r--r--src/nvim/version.c2
3 files changed, 113 insertions, 4 deletions
diff --git a/src/nvim/eval/encode.c b/src/nvim/eval/encode.c
index 57507f4430..65570a6f30 100644
--- a/src/nvim/eval/encode.c
+++ b/src/nvim/eval/encode.c
@@ -317,9 +317,32 @@ int encode_read_from_list(ListReaderState *const state, char *const buf,
#define TYPVAL_ENCODE_CONV_PARTIAL(partial) \
do { \
- ga_concat(gap, "partial("); \
- TYPVAL_ENCODE_CONV_STRING(partial, STRLEN(partial)); \
- ga_append(gap, ')'); \
+ partial_T *pt = tv->vval.v_partial; \
+ garray_T ga; \
+ int i; \
+ ga_init(&ga, 1, 100); \
+ ga_concat(&ga, (char_u *)"function("); \
+ if (&pt->pt_name != NULL) { \
+ TYPVAL_ENCODE_CONV_STRING((char *)pt->pt_name, sizeof(pt->pt_name)); \
+ } \
+ if (pt != NULL && pt->pt_argc > 0) { \
+ ga_concat(&ga, (char_u *)", ["); \
+ for (i = 0; i < pt->pt_argc; i++) { \
+ if (i > 0) { \
+ ga_concat(&ga, (char_u *)", "); \
+ } \
+ ga_concat(&ga, encode_tv2string(&pt->pt_argv[i], NULL)); \
+ } \
+ ga_concat(&ga, (char_u *)"]"); \
+ } \
+ if (pt != NULL && pt->pt_dict != NULL) { \
+ typval_T dtv; \
+ ga_concat(&ga, (char_u *)", "); \
+ dtv.v_type = VAR_DICT; \
+ dtv.vval.v_dict = pt->pt_dict; \
+ ga_concat(&ga, encode_tv2string(&dtv, NULL)); \
+ } \
+ ga_concat(&ga, (char_u *)")"); \
} while (0)
#define TYPVAL_ENCODE_CONV_EMPTY_LIST() \
diff --git a/src/nvim/testdir/test_partial.vim b/src/nvim/testdir/test_partial.vim
index 2b6b56c358..b5909910c7 100644
--- a/src/nvim/testdir/test_partial.vim
+++ b/src/nvim/testdir/test_partial.vim
@@ -155,3 +155,89 @@ func Test_partial_exists()
let lF = [F]
call assert_true(exists('*lF[0]'))
endfunc
+
+func Test_partial_string()
+ let F = function('MyFunc')
+ call assert_equal("function('MyFunc')", string(F))
+ let F = function('MyFunc', ['foo'])
+ call assert_equal("function('MyFunc', ['foo'])", string(F))
+ let F = function('MyFunc', ['foo', 'bar'])
+ call assert_equal("function('MyFunc', ['foo', 'bar'])", string(F))
+ let d = {'one': 1}
+ let F = function('MyFunc', d)
+ call assert_equal("function('MyFunc', {'one': 1})", string(F))
+ let F = function('MyFunc', ['foo'], d)
+ call assert_equal("function('MyFunc', ['foo'], {'one': 1})", string(F))
+endfunc
+
+func Test_func_unref()
+ let obj = {}
+ function! obj.func() abort
+ endfunction
+ let funcnumber = matchstr(string(obj.func), '^function(''\zs.\{-}\ze''')
+ call assert_true(exists('*{' . funcnumber . '}'))
+ unlet obj
+ call assert_false(exists('*{' . funcnumber . '}'))
+endfunc
+
+func Test_redefine_dict_func()
+ let d = {}
+ function d.test4()
+ endfunction
+ let d.test4 = d.test4
+ try
+ function! d.test4(name)
+ endfunction
+ catch
+ call assert_true(v:errmsg, v:exception)
+ endtry
+endfunc
+
+" This causes double free on exit if EXITFREE is defined.
+func Test_cyclic_list_arg()
+ let l = []
+ let Pt = function('string', [l])
+ call add(l, Pt)
+ unlet l
+ unlet Pt
+endfunc
+
+" This causes double free on exit if EXITFREE is defined.
+func Test_cyclic_dict_arg()
+ let d = {}
+ let Pt = function('string', [d])
+ let d.Pt = Pt
+ unlet d
+ unlet Pt
+endfunc
+
+func Test_auto_partial_rebind()
+ let dict1 = {'name': 'dict1'}
+ func! dict1.f1()
+ return self.name
+ endfunc
+ let dict1.f2 = function(dict1.f1, dict1)
+
+ call assert_equal('dict1', dict1.f1())
+ call assert_equal('dict1', dict1['f1']())
+ call assert_equal('dict1', dict1.f2())
+ call assert_equal('dict1', dict1['f2']())
+
+ let dict2 = {'name': 'dict2'}
+ let dict2.f1 = dict1.f1
+ let dict2.f2 = dict1.f2
+
+ call assert_equal('dict2', dict2.f1())
+ call assert_equal('dict2', dict2['f1']())
+ call assert_equal('dict1', dict2.f2())
+ call assert_equal('dict1', dict2['f2']())
+endfunc
+
+func Test_get_partial_items()
+ let dict = {'name': 'hello'}
+ let Cb = function('MyDictFunc', ["foo", "bar"], dict)
+ call assert_equal('MyDictFunc', get(Cb, 'func'))
+ call assert_equal(["foo", "bar"], get(Cb, 'args'))
+ call assert_equal(dict, get(Cb, 'dict'))
+ call assert_fails('call get(Cb, "xxx")', 'E475:')
+endfunc
diff --git a/src/nvim/version.c b/src/nvim/version.c
index 442598c643..6bf99ca410 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -834,7 +834,7 @@ static int included_patches[] = {
// 1611 NA
// 1610 NA
// 1609 NA
- // 1608,
+ 1608,
1607,
1606,
1605,