From 6af24b2457752c0d36aaf9f29f03d39afd09937f Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 13 Apr 2024 09:39:57 +0200 Subject: Merging upstream version 2:9.1.0199. Signed-off-by: Daniel Baumann --- src/userfunc.c | 113 +++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 77 insertions(+), 36 deletions(-) (limited to 'src/userfunc.c') diff --git a/src/userfunc.c b/src/userfunc.c index 64761ec..ce144a3 100644 --- a/src/userfunc.c +++ b/src/userfunc.c @@ -4459,12 +4459,13 @@ trans_function_name_ext( } } // The function name must start with an upper case letter (unless it is a - // Vim9 class new() function or a Vim9 class private method) + // Vim9 class new() function or a Vim9 class private method or one of the + // supported Vim9 object builtin functions) else if (!(flags & TFN_INT) && (builtin_function(lv.ll_name, len) || (vim9script && *lv.ll_name == '_')) && !((flags & TFN_IN_CLASS) - && (STRNCMP(lv.ll_name, "new", 3) == 0 + && (is_valid_builtin_obj_methodname(lv.ll_name) || (*lv.ll_name == '_')))) { semsg(_(vim9script ? e_function_name_must_start_with_capital_str @@ -4976,7 +4977,10 @@ define_function( : eval_isnamec(name_base[i])); ++i) ; if (name_base[i] != NUL) + { emsg_funcname(e_invalid_argument_str, arg); + goto ret_free; + } // In Vim9 script a function cannot have the same name as a // variable. @@ -5545,6 +5549,60 @@ find_func_by_name(char_u *name, compiletype_T *compile_type) return ufunc; } +/* + * Compile the :def function "ufunc". If "cl" is not NULL, then compile the + * class or object method "ufunc" in "cl". + */ + void +defcompile_function(ufunc_T *ufunc, class_T *cl) +{ + compiletype_T compile_type = CT_NONE; + + if (func_needs_compiling(ufunc, compile_type)) + (void)compile_def_function(ufunc, FALSE, compile_type, NULL); + else + smsg(_("Function %s%s%s does not need compiling"), + cl != NULL ? cl->class_name : (char_u *)"", + cl != NULL ? (char_u *)"." : (char_u *)"", + ufunc->uf_name); +} + +/* + * Compile all the :def functions defined in the current script + */ + static void +defcompile_funcs_in_script(void) +{ + long todo = (long)func_hashtab.ht_used; + int changed = func_hashtab.ht_changed; + hashitem_T *hi; + + for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) + { + if (!HASHITEM_EMPTY(hi)) + { + --todo; + 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) + { + (void)compile_def_function(ufunc, FALSE, CT_NONE, NULL); + + if (func_hashtab.ht_changed != changed) + { + // a function has been added or removed, need to start + // over + todo = (long)func_hashtab.ht_used; + changed = func_hashtab.ht_changed; + hi = func_hashtab.ht_array; + --hi; + } + } + } + } +} + /* * :defcompile - compile all :def functions in the current script that need to * be compiled or the one specified by the argument. @@ -5555,46 +5613,29 @@ ex_defcompile(exarg_T *eap) { if (*eap->arg != NUL) { - compiletype_T compile_type = CT_NONE; - ufunc_T *ufunc = find_func_by_name(eap->arg, &compile_type); - if (ufunc != NULL) + typval_T tv; + + if (is_class_name(eap->arg, &tv)) { - if (func_needs_compiling(ufunc, compile_type)) - (void)compile_def_function(ufunc, FALSE, compile_type, NULL); - else - smsg(_("Function %s does not need compiling"), eap->arg); + class_T *cl = tv.vval.v_class; + + if (cl != NULL) + defcompile_class(cl); + } + else + { + compiletype_T compile_type = CT_NONE; + ufunc_T *ufunc = find_func_by_name(eap->arg, &compile_type); + if (ufunc != NULL) + defcompile_function(ufunc, NULL); } } else { - long todo = (long)func_hashtab.ht_used; - int changed = func_hashtab.ht_changed; - hashitem_T *hi; - - for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) - { - if (!HASHITEM_EMPTY(hi)) - { - --todo; - 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) - { - (void)compile_def_function(ufunc, FALSE, CT_NONE, NULL); + defcompile_funcs_in_script(); - if (func_hashtab.ht_changed != changed) - { - // a function has been added or removed, need to start - // over - todo = (long)func_hashtab.ht_used; - changed = func_hashtab.ht_changed; - hi = func_hashtab.ht_array; - --hi; - } - } - } - } + // compile all the class defined in the current script + defcompile_classes_in_script(); } } -- cgit v1.2.3