comparison src/userfunc.c @ 26506:4a1d2abc2016 v8.2.3783

patch 8.2.3783: confusing error for using a variable as a function Commit: https://github.com/vim/vim/commit/2ef9156b4284e4a52613c36e3d4667245273a28d Author: Bram Moolenaar <Bram@vim.org> Date: Sat Dec 11 16:14:07 2021 +0000 patch 8.2.3783: confusing error for using a variable as a function Problem: Confusing error for using a variable as a function. Solution: If a function is not found but there is a variable, give a more useful error. (issue #9310)
author Bram Moolenaar <Bram@vim.org>
date Sat, 11 Dec 2021 17:15:03 +0100
parents 7821550ba3a8
children 2fbd05a873e3
comparison
equal deleted inserted replaced
26505:6db198ec38ac 26506:4a1d2abc2016
1542 * name it contains, otherwise return "name". 1542 * name it contains, otherwise return "name".
1543 * If "partialp" is not NULL, and "name" is of type VAR_PARTIAL also set 1543 * If "partialp" is not NULL, and "name" is of type VAR_PARTIAL also set
1544 * "partialp". 1544 * "partialp".
1545 * If "type" is not NULL and a Vim9 script-local variable is found look up the 1545 * If "type" is not NULL and a Vim9 script-local variable is found look up the
1546 * type of the variable. 1546 * type of the variable.
1547 * If "found_var" is not NULL and a variable was found set it to TRUE.
1547 */ 1548 */
1548 char_u * 1549 char_u *
1549 deref_func_name( 1550 deref_func_name(
1550 char_u *name, 1551 char_u *name,
1551 int *lenp, 1552 int *lenp,
1552 partial_T **partialp, 1553 partial_T **partialp,
1553 type_T **type, 1554 type_T **type,
1554 int no_autoload) 1555 int no_autoload,
1556 int *found_var)
1555 { 1557 {
1556 dictitem_T *v; 1558 dictitem_T *v;
1557 typval_T *tv = NULL; 1559 typval_T *tv = NULL;
1558 int cc; 1560 int cc;
1559 char_u *s = NULL; 1561 char_u *s = NULL;
1607 } 1609 }
1608 } 1610 }
1609 1611
1610 if (tv != NULL) 1612 if (tv != NULL)
1611 { 1613 {
1614 if (found_var != NULL)
1615 *found_var = TRUE;
1612 if (tv->v_type == VAR_FUNC) 1616 if (tv->v_type == VAR_FUNC)
1613 { 1617 {
1614 if (tv->vval.v_string == NULL) 1618 if (tv->vval.v_string == NULL)
1615 { 1619 {
1616 *lenp = 0; 1620 *lenp = 0;
3197 /* 3201 /*
3198 * Give an error message for the result of a function. 3202 * Give an error message for the result of a function.
3199 * Nothing if "error" is FCERR_NONE. 3203 * Nothing if "error" is FCERR_NONE.
3200 */ 3204 */
3201 void 3205 void
3202 user_func_error(int error, char_u *name) 3206 user_func_error(int error, char_u *name, funcexe_T *funcexe)
3203 { 3207 {
3204 switch (error) 3208 switch (error)
3205 { 3209 {
3206 case FCERR_UNKNOWN: 3210 case FCERR_UNKNOWN:
3207 emsg_funcname(e_unknownfunc, name); 3211 if (funcexe->fe_found_var)
3212 semsg(_(e_not_callable_type_str), name);
3213 else
3214 emsg_funcname(e_unknownfunc, name);
3208 break; 3215 break;
3209 case FCERR_NOTMETHOD: 3216 case FCERR_NOTMETHOD:
3210 emsg_funcname( 3217 emsg_funcname(
3211 N_("E276: Cannot use function as a method: %s"), name); 3218 N_("E276: Cannot use function as a method: %s"), name);
3212 break; 3219 break;
3446 * Report an error unless the argument evaluation or function call has been 3453 * Report an error unless the argument evaluation or function call has been
3447 * cancelled due to an aborting error, an interrupt, or an exception. 3454 * cancelled due to an aborting error, an interrupt, or an exception.
3448 */ 3455 */
3449 if (!aborting()) 3456 if (!aborting())
3450 { 3457 {
3451 user_func_error(error, (name != NULL) ? name : funcname); 3458 user_func_error(error, (name != NULL) ? name : funcname, funcexe);
3452 } 3459 }
3453 3460
3454 // clear the copies made from the partial 3461 // clear the copies made from the partial
3455 while (argv_clear > 0) 3462 while (argv_clear > 0)
3456 clear_tv(&argv[--argv_clear + argv_base]); 3463 clear_tv(&argv[--argv_clear + argv_base]);
3675 // Check if the name is a Funcref. If so, use the value. 3682 // Check if the name is a Funcref. If so, use the value.
3676 if (lv.ll_exp_name != NULL) 3683 if (lv.ll_exp_name != NULL)
3677 { 3684 {
3678 len = (int)STRLEN(lv.ll_exp_name); 3685 len = (int)STRLEN(lv.ll_exp_name);
3679 name = deref_func_name(lv.ll_exp_name, &len, partial, type, 3686 name = deref_func_name(lv.ll_exp_name, &len, partial, type,
3680 flags & TFN_NO_AUTOLOAD); 3687 flags & TFN_NO_AUTOLOAD, NULL);
3681 if (name == lv.ll_exp_name) 3688 if (name == lv.ll_exp_name)
3682 name = NULL; 3689 name = NULL;
3683 } 3690 }
3684 else if (!(flags & TFN_NO_DEREF)) 3691 else if (!(flags & TFN_NO_DEREF))
3685 { 3692 {
3686 len = (int)(end - *pp); 3693 len = (int)(end - *pp);
3687 name = deref_func_name(*pp, &len, partial, type, 3694 name = deref_func_name(*pp, &len, partial, type,
3688 flags & TFN_NO_AUTOLOAD); 3695 flags & TFN_NO_AUTOLOAD, NULL);
3689 if (name == *pp) 3696 if (name == *pp)
3690 name = NULL; 3697 name = NULL;
3691 } 3698 }
3692 if (name != NULL) 3699 if (name != NULL)
3693 { 3700 {
5002 int failed = FALSE; 5009 int failed = FALSE;
5003 funcdict_T fudi; 5010 funcdict_T fudi;
5004 partial_T *partial = NULL; 5011 partial_T *partial = NULL;
5005 evalarg_T evalarg; 5012 evalarg_T evalarg;
5006 type_T *type = NULL; 5013 type_T *type = NULL;
5014 int found_var = FALSE;
5007 5015
5008 fill_evalarg_from_eap(&evalarg, eap, eap->skip); 5016 fill_evalarg_from_eap(&evalarg, eap, eap->skip);
5009 if (eap->skip) 5017 if (eap->skip)
5010 { 5018 {
5011 // trans_function_name() doesn't work well when skipping, use eval0() 5019 // trans_function_name() doesn't work well when skipping, use eval0()
5038 // If it is the name of a variable of type VAR_FUNC or VAR_PARTIAL use its 5046 // If it is the name of a variable of type VAR_FUNC or VAR_PARTIAL use its
5039 // contents. For VAR_PARTIAL get its partial, unless we already have one 5047 // contents. For VAR_PARTIAL get its partial, unless we already have one
5040 // from trans_function_name(). 5048 // from trans_function_name().
5041 len = (int)STRLEN(tofree); 5049 len = (int)STRLEN(tofree);
5042 name = deref_func_name(tofree, &len, partial != NULL ? NULL : &partial, 5050 name = deref_func_name(tofree, &len, partial != NULL ? NULL : &partial,
5043 in_vim9script() && type == NULL ? &type : NULL, FALSE); 5051 in_vim9script() && type == NULL ? &type : NULL, FALSE, &found_var);
5044 5052
5045 // Skip white space to allow ":call func ()". Not good, but required for 5053 // Skip white space to allow ":call func ()". Not good, but required for
5046 // backward compatibility. 5054 // backward compatibility.
5047 startarg = skipwhite(arg); 5055 startarg = skipwhite(arg);
5048 if (*startarg != '(') 5056 if (*startarg != '(')
5094 funcexe.doesrange = &doesrange; 5102 funcexe.doesrange = &doesrange;
5095 funcexe.evaluate = !eap->skip; 5103 funcexe.evaluate = !eap->skip;
5096 funcexe.partial = partial; 5104 funcexe.partial = partial;
5097 funcexe.selfdict = fudi.fd_dict; 5105 funcexe.selfdict = fudi.fd_dict;
5098 funcexe.check_type = type; 5106 funcexe.check_type = type;
5107 funcexe.fe_found_var = found_var;
5099 rettv.v_type = VAR_UNKNOWN; // clear_tv() uses this 5108 rettv.v_type = VAR_UNKNOWN; // clear_tv() uses this
5100 if (get_func_tv(name, -1, &rettv, &arg, &evalarg, &funcexe) == FAIL) 5109 if (get_func_tv(name, -1, &rettv, &arg, &evalarg, &funcexe) == FAIL)
5101 { 5110 {
5102 failed = TRUE; 5111 failed = TRUE;
5103 break; 5112 break;