Mercurial > vim
diff src/userfunc.c @ 34112:0f2632b04cde v9.1.0020
patch 9.1.0020: Vim9: cannot compile all methods in a class
Commit: https://github.com/vim/vim/commit/4f32c83a775a195ae7e1545b2840fb773f93414f
Author: Yegappan Lakshmanan <yegappan@yahoo.com>
Date: Fri Jan 12 17:36:40 2024 +0100
patch 9.1.0020: Vim9: cannot compile all methods in a class
Problem: Vim9: cannot compile all methods in a class
Solution: Support compiling all the methods in a class using :defcompile
(Yegappan Lakshmanan)
closes: #13844
Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Fri, 12 Jan 2024 17:45:08 +0100 |
parents | 1629cc65d78d |
children | 5c1a025192ed |
line wrap: on
line diff
--- a/src/userfunc.c +++ b/src/userfunc.c @@ -5546,6 +5546,60 @@ find_func_by_name(char_u *name, compilet } /* + * 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. * Skips dead functions. Doesn't do profiling. @@ -5555,46 +5609,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) - { - 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); + typval_T tv; + + if (is_class_name(eap->arg, &tv)) + { + 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); - - 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_funcs_in_script(); + + // compile all the class defined in the current script + defcompile_classes_in_script(); } }