Mercurial > vim
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; |