if (cl != NULL)
{
lp->ll_valtype = NULL;
- int count = v_type == VAR_OBJECT ? cl->class_obj_member_count
- : cl->class_class_member_count;
- ocmember_T *members = v_type == VAR_OBJECT
- ? cl->class_obj_members
- : cl->class_class_members;
- for (int i = 0; i < count; ++i)
+
+ if (flags & GLV_PREFER_FUNC)
{
- ocmember_T *om = members + i;
- if (STRNCMP(om->ocm_name, key, p - key) == 0
- && om->ocm_name[p - key] == NUL)
+ // First look for a function with this name.
+ // round 1: class functions (skipped for an object)
+ // round 2: object methods
+ for (int round = v_type == VAR_OBJECT ? 2 : 1;
+ round <= 2; ++round)
{
- switch (om->ocm_access)
+ int count = round == 1
+ ? cl->class_class_function_count
+ : cl->class_obj_method_count;
+ ufunc_T **funcs = round == 1
+ ? cl->class_class_functions
+ : cl->class_obj_methods;
+ for (int i = 0; i < count; ++i)
{
- case ACCESS_PRIVATE:
- semsg(_(e_cannot_access_private_member_str),
- om->ocm_name);
- return NULL;
- case ACCESS_READ:
- if (!(flags & GLV_READ_ONLY))
- {
- semsg(_(e_member_is_not_writable_str),
+ ufunc_T *fp = funcs[i];
+ char_u *ufname = (char_u *)fp->uf_name;
+ if (STRNCMP(ufname, key, p - key) == 0
+ && ufname[p - key] == NUL)
+ {
+ lp->ll_ufunc = fp;
+ lp->ll_valtype = fp->uf_func_type;
+ round = 3;
+ break;
+ }
+ }
+ }
+ }
+
+ if (lp->ll_valtype == NULL)
+ {
+ int count = v_type == VAR_OBJECT
+ ? cl->class_obj_member_count
+ : cl->class_class_member_count;
+ ocmember_T *members = v_type == VAR_OBJECT
+ ? cl->class_obj_members
+ : cl->class_class_members;
+ for (int i = 0; i < count; ++i)
+ {
+ ocmember_T *om = members + i;
+ if (STRNCMP(om->ocm_name, key, p - key) == 0
+ && om->ocm_name[p - key] == NUL)
+ {
+ switch (om->ocm_access)
+ {
+ case ACCESS_PRIVATE:
+ semsg(_(e_cannot_access_private_member_str),
om->ocm_name);
return NULL;
- }
- break;
- case ACCESS_ALL:
- break;
- }
+ case ACCESS_READ:
+ if ((flags & GLV_READ_ONLY) == 0)
+ {
+ semsg(_(e_member_is_not_writable_str),
+ om->ocm_name);
+ return NULL;
+ }
+ break;
+ case ACCESS_ALL:
+ break;
+ }
- lp->ll_valtype = om->ocm_type;
+ lp->ll_valtype = om->ocm_type;
- if (v_type == VAR_OBJECT)
- lp->ll_tv = ((typval_T *)(
+ if (v_type == VAR_OBJECT)
+ lp->ll_tv = ((typval_T *)(
lp->ll_tv->vval.v_object + 1)) + i;
- else
- lp->ll_tv = &cl->class_members_tv[i];
- break;
+ else
+ lp->ll_tv = &cl->class_members_tv[i];
+ break;
+ }
}
}
+
if (lp->ll_valtype == NULL)
{
if (v_type == VAR_OBJECT)
int call_func(char_u *funcname, int len, typval_T *rettv, int argcount_in, typval_T *argvars_in, funcexe_T *funcexe);
int call_simple_func(char_u *funcname, int len, typval_T *rettv);
char_u *printable_func_name(ufunc_T *fp);
-char_u *trans_function_name(char_u **pp, int *is_global, int skip, int flags, funcdict_T *fdp, partial_T **partial, type_T **type);
+char_u *trans_function_name(char_u **pp, int *is_global, int skip, int flags);
+char_u *trans_function_name_ext(char_u **pp, int *is_global, int skip, int flags, funcdict_T *fdp, partial_T **partial, type_T **type, ufunc_T **ufunc);
char_u *get_scriptlocal_funcname(char_u *funcname);
char_u *alloc_printable_func_name(char_u *fname);
char_u *save_function_name(char_u **name, int *is_global, int skip, int flags, funcdict_T *fudi);
if (*p == '!')
p = skipwhite(p + 1);
p += eval_fname_script(p);
- vim_free(trans_function_name(&p, NULL, TRUE, 0, NULL,
- NULL, NULL));
+ vim_free(trans_function_name(&p, NULL, TRUE, 0));
if (*skipwhite(p) == '(')
{
if (nesting == MAX_FUNC_NESTING - 1)
*/
char_u *
trans_function_name(
+ char_u **pp,
+ int *is_global,
+ int skip, // only find the end, don't evaluate
+ int flags)
+{
+ return trans_function_name_ext(pp, is_global, skip, flags,
+ NULL, NULL, NULL, NULL);
+}
+
+/*
+ * trans_function_name() with extra arguments.
+ * "fdp", "partial", "type" and "ufunc" can be NULL.
+ */
+ char_u *
+trans_function_name_ext(
char_u **pp,
int *is_global,
int skip, // only find the end, don't evaluate
int flags,
funcdict_T *fdp, // return: info about dictionary used
partial_T **partial, // return: partial of a FuncRef
- type_T **type) // return: type of funcref if not NULL
+ type_T **type, // return: type of funcref
+ ufunc_T **ufunc) // return: function
{
char_u *name = NULL;
char_u *start;
start += lead;
// Note that TFN_ flags use the same values as GLV_ flags.
- end = get_lval(start, NULL, &lv, FALSE, skip, flags | GLV_READ_ONLY,
+ end = get_lval(start, NULL, &lv, FALSE, skip,
+ flags | GLV_READ_ONLY | GLV_PREFER_FUNC,
lead > 2 ? 0 : FNE_CHECK_START);
if (end == start || (vim9script && end != NULL
&& end[-1] == AUTOLOAD_CHAR && *end == '('))
goto theend;
}
+ if (lv.ll_ufunc != NULL)
+ {
+ *ufunc = lv.ll_ufunc;
+ name = vim_strsave(lv.ll_ufunc->uf_name);
+ goto theend;
+ }
+
if (lv.ll_tv != NULL)
{
if (fdp != NULL)
CLEAR_POINTER(fudi);
}
else
- saved = trans_function_name(&p, is_global, skip,
- flags, fudi, NULL, NULL);
+ saved = trans_function_name_ext(&p, is_global, skip,
+ flags, fudi, NULL, NULL, NULL);
*name = p;
return saved;
}
}
else
{
- // First try finding a method in a class, find_func_by_name() will give
- // an error if the function is not found.
+ // First try finding a method in a class, trans_function_name() will
+ // give an error if the function is not found.
ufunc = find_class_func(&arg);
if (ufunc != NULL)
return ufunc;
- fname = trans_function_name(&arg, &is_global, FALSE,
+ fname = trans_function_name_ext(&arg, &is_global, FALSE,
TFN_INT | TFN_QUIET | TFN_NO_AUTOLOAD | TFN_NO_DECL,
- NULL, NULL, NULL);
+ NULL, NULL, NULL, &ufunc);
+ if (ufunc != NULL)
+ {
+ vim_free(fname);
+ return ufunc;
+ }
}
if (fname == NULL)
{
void
ex_defcompile(exarg_T *eap)
{
- ufunc_T *ufunc;
-
if (*eap->arg != NUL)
{
compiletype_T compile_type = CT_NONE;
-
- ufunc = find_func_by_name(eap->arg, &compile_type);
+ ufunc_T *ufunc = find_func_by_name(eap->arg, &compile_type);
if (ufunc != NULL)
{
if (func_needs_compiling(ufunc, compile_type))
if (!HASHITEM_EMPTY(hi))
{
--todo;
- ufunc = HI2UF(hi);
+ ufunc_T *ufunc = HI2UF(hi);
if (ufunc->uf_script_ctx.sc_sid == current_sctx.sc_sid
&& ufunc->uf_def_status == UF_TO_BE_COMPILED
&& (ufunc->uf_flags & FC_DEAD) == 0)
flag = TFN_INT | TFN_QUIET | TFN_NO_AUTOLOAD;
if (no_deref)
flag |= TFN_NO_DEREF;
- p = trans_function_name(&nm, &is_global, FALSE, flag, NULL, NULL, NULL);
+ p = trans_function_name(&nm, &is_global, FALSE, flag);
nm = skipwhite(nm);
// Only accept "funcname", "funcname ", "funcname (..." and
char_u *p;
int is_global = FALSE;
- p = trans_function_name(&nm, &is_global, FALSE,
- TFN_INT|TFN_QUIET, NULL, NULL, NULL);
+ p = trans_function_name(&nm, &is_global, FALSE, TFN_INT|TFN_QUIET);
if (p != NULL && *nm == NUL
&& (!check || translated_function_exists(p, is_global)))
int is_global = FALSE;
p = eap->arg;
- name = trans_function_name(&p, &is_global, eap->skip, 0, &fudi,
- NULL, NULL);
+ name = trans_function_name_ext(&p, &is_global, eap->skip, 0, &fudi,
+ NULL, NULL, NULL);
vim_free(fudi.fd_newkey);
if (name == NULL)
{
return;
}
- tofree = trans_function_name(&arg, NULL, eap->skip, TFN_INT,
- &fudi, &partial, vim9script ? &type : NULL);
+ tofree = trans_function_name_ext(&arg, NULL, eap->skip, TFN_INT,
+ &fudi, &partial, vim9script ? &type : NULL, NULL);
if (fudi.fd_newkey != NULL)
{
// Still need to give an error message for missing key.