diff options
author | Michael Ennen <mike.ennen@gmail.com> | 2016-10-28 22:44:42 -0700 |
---|---|---|
committer | James McCoy <jamessan@jamessan.com> | 2016-12-12 10:17:35 -0500 |
commit | bae31b764a5607fad5d914f271e93e10c2d0bfbe (patch) | |
tree | e3af8d044005cd673f90ba33974675f92ef4347b | |
parent | 3213b28c01313c7f0e7e0e01f72a0fbfef85fa3e (diff) | |
download | rneovim-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.c | 29 | ||||
-rw-r--r-- | src/nvim/testdir/test_partial.vim | 86 | ||||
-rw-r--r-- | src/nvim/version.c | 2 |
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, |