Mercurial > vim
comparison src/eval.c @ 8575:b5209a4e5baf v7.4.1577
commit https://github.com/vim/vim/commit/ab1fa3955f25dfdb7e329c3bd76e175c93c8cb5e
Author: Bram Moolenaar <Bram@vim.org>
Date: Tue Mar 15 19:33:34 2016 +0100
patch 7.4.1577
Problem: Cannot pass "dict.Myfunc" around as a partial.
Solution: Create a partial when expected.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Tue, 15 Mar 2016 19:45:06 +0100 |
parents | 7d3548ae729d |
children | 63dc856bd13d |
comparison
equal
deleted
inserted
replaced
8574:a192274c1ac6 | 8575:b5209a4e5baf |
---|---|
108 static char *e_nofunc = N_("E130: Unknown function: %s"); | 108 static char *e_nofunc = N_("E130: Unknown function: %s"); |
109 static char *e_illvar = N_("E461: Illegal variable name: %s"); | 109 static char *e_illvar = N_("E461: Illegal variable name: %s"); |
110 #ifdef FEAT_FLOAT | 110 #ifdef FEAT_FLOAT |
111 static char *e_float_as_string = N_("E806: using Float as a String"); | 111 static char *e_float_as_string = N_("E806: using Float as a String"); |
112 #endif | 112 #endif |
113 static char *e_dict_both = N_("E924: can't have both a \"self\" dict and a partial: %s"); | |
113 | 114 |
114 #define NAMESPACE_CHAR (char_u *)"abglstvw" | 115 #define NAMESPACE_CHAR (char_u *)"abglstvw" |
115 | 116 |
116 static dictitem_T globvars_var; /* variable used for g: */ | 117 static dictitem_T globvars_var; /* variable used for g: */ |
117 #define globvarht globvardict.dv_hashtab | 118 #define globvarht globvardict.dv_hashtab |
8910 case ERROR_DICT: | 8911 case ERROR_DICT: |
8911 emsg_funcname(N_("E725: Calling dict function without Dictionary: %s"), | 8912 emsg_funcname(N_("E725: Calling dict function without Dictionary: %s"), |
8912 name); | 8913 name); |
8913 break; | 8914 break; |
8914 case ERROR_BOTH: | 8915 case ERROR_BOTH: |
8915 emsg_funcname(N_("E924: can't have both a \"self\" dict and a partial: %s"), | 8916 emsg_funcname(e_dict_both, name); |
8916 name); | |
8917 break; | 8917 break; |
8918 } | 8918 } |
8919 } | 8919 } |
8920 | 8920 |
8921 while (argv_clear > 0) | 8921 while (argv_clear > 0) |
11780 static void | 11780 static void |
11781 f_function(typval_T *argvars, typval_T *rettv) | 11781 f_function(typval_T *argvars, typval_T *rettv) |
11782 { | 11782 { |
11783 char_u *s; | 11783 char_u *s; |
11784 char_u *name; | 11784 char_u *name; |
11785 | 11785 int use_string = FALSE; |
11786 s = get_tv_string(&argvars[0]); | 11786 |
11787 if (s == NULL || *s == NUL || VIM_ISDIGIT(*s)) | 11787 if (argvars[0].v_type == VAR_FUNC) |
11788 { | |
11789 /* function(MyFunc, [arg], dict) */ | |
11790 s = argvars[0].vval.v_string; | |
11791 } | |
11792 else if (argvars[0].v_type == VAR_PARTIAL | |
11793 && argvars[0].vval.v_partial != NULL) | |
11794 /* function(dict.MyFunc, [arg]) */ | |
11795 s = argvars[0].vval.v_partial->pt_name; | |
11796 else | |
11797 { | |
11798 /* function('MyFunc', [arg], dict) */ | |
11799 s = get_tv_string(&argvars[0]); | |
11800 use_string = TRUE; | |
11801 } | |
11802 | |
11803 if (s == NULL || *s == NUL || (use_string && VIM_ISDIGIT(*s))) | |
11788 EMSG2(_(e_invarg2), s); | 11804 EMSG2(_(e_invarg2), s); |
11789 /* Don't check an autoload name for existence here. */ | 11805 /* Don't check an autoload name for existence here. */ |
11790 else if (vim_strchr(s, AUTOLOAD_CHAR) == NULL && !function_exists(s)) | 11806 else if (use_string && vim_strchr(s, AUTOLOAD_CHAR) == NULL |
11807 && !function_exists(s)) | |
11791 EMSG2(_("E700: Unknown function: %s"), s); | 11808 EMSG2(_("E700: Unknown function: %s"), s); |
11792 else | 11809 else |
11793 { | 11810 { |
11794 int dict_idx = 0; | 11811 int dict_idx = 0; |
11795 int arg_idx = 0; | 11812 int arg_idx = 0; |
11835 { | 11852 { |
11836 EMSG(_("E922: expected a dict")); | 11853 EMSG(_("E922: expected a dict")); |
11837 vim_free(name); | 11854 vim_free(name); |
11838 return; | 11855 return; |
11839 } | 11856 } |
11857 if (argvars[0].v_type == VAR_PARTIAL) | |
11858 { | |
11859 EMSG2(_(e_dict_both), name); | |
11860 vim_free(name); | |
11861 return; | |
11862 } | |
11840 if (argvars[dict_idx].vval.v_dict == NULL) | 11863 if (argvars[dict_idx].vval.v_dict == NULL) |
11841 dict_idx = 0; | 11864 dict_idx = 0; |
11842 } | 11865 } |
11843 if (arg_idx > 0) | 11866 if (arg_idx > 0) |
11844 { | 11867 { |
11878 for (li = list->lv_first; li != NULL; li = li->li_next) | 11901 for (li = list->lv_first; li != NULL; li = li->li_next) |
11879 copy_tv(&li->li_tv, &pt->pt_argv[i++]); | 11902 copy_tv(&li->li_tv, &pt->pt_argv[i++]); |
11880 } | 11903 } |
11881 } | 11904 } |
11882 | 11905 |
11883 if (dict_idx > 0) | 11906 if (argvars[0].v_type == VAR_PARTIAL) |
11907 { | |
11908 pt->pt_dict = argvars[0].vval.v_partial->pt_dict; | |
11909 ++pt->pt_dict->dv_refcount; | |
11910 } | |
11911 else if (dict_idx > 0) | |
11884 { | 11912 { |
11885 pt->pt_dict = argvars[dict_idx].vval.v_dict; | 11913 pt->pt_dict = argvars[dict_idx].vval.v_dict; |
11886 ++pt->pt_dict->dv_refcount; | 11914 ++pt->pt_dict->dv_refcount; |
11887 } | 11915 } |
11888 | 11916 |
21531 { | 21559 { |
21532 functv = *rettv; | 21560 functv = *rettv; |
21533 rettv->v_type = VAR_UNKNOWN; | 21561 rettv->v_type = VAR_UNKNOWN; |
21534 | 21562 |
21535 /* Invoke the function. Recursive! */ | 21563 /* Invoke the function. Recursive! */ |
21536 if (rettv->v_type == VAR_PARTIAL) | 21564 if (functv.v_type == VAR_PARTIAL) |
21537 { | 21565 { |
21538 pt = functv.vval.v_partial; | 21566 pt = functv.vval.v_partial; |
21539 s = pt->pt_name; | 21567 s = pt->pt_name; |
21540 } | 21568 } |
21541 else | 21569 else |
21580 clear_tv(rettv); | 21608 clear_tv(rettv); |
21581 ret = FAIL; | 21609 ret = FAIL; |
21582 } | 21610 } |
21583 } | 21611 } |
21584 } | 21612 } |
21613 | |
21614 if (rettv->v_type == VAR_FUNC && selfdict != NULL) | |
21615 { | |
21616 partial_T *pt = (partial_T *)alloc_clear(sizeof(partial_T)); | |
21617 | |
21618 /* Turn "dict.Func" into a partial for "Func" with "dict". */ | |
21619 if (pt != NULL) | |
21620 { | |
21621 pt->pt_dict = selfdict; | |
21622 selfdict = NULL; | |
21623 pt->pt_name = rettv->vval.v_string; | |
21624 func_ref(pt->pt_name); | |
21625 rettv->v_type = VAR_PARTIAL; | |
21626 rettv->vval.v_partial = pt; | |
21627 } | |
21628 } | |
21629 | |
21585 dict_unref(selfdict); | 21630 dict_unref(selfdict); |
21586 return ret; | 21631 return ret; |
21587 } | 21632 } |
21588 | 21633 |
21589 /* | 21634 /* |