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 /*