comparison 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
comparison
equal deleted inserted replaced
34111:204b15645ef4 34112:0f2632b04cde
5544 semsg(_(e_cannot_find_function_str), name); 5544 semsg(_(e_cannot_find_function_str), name);
5545 return ufunc; 5545 return ufunc;
5546 } 5546 }
5547 5547
5548 /* 5548 /*
5549 * Compile the :def function "ufunc". If "cl" is not NULL, then compile the
5550 * class or object method "ufunc" in "cl".
5551 */
5552 void
5553 defcompile_function(ufunc_T *ufunc, class_T *cl)
5554 {
5555 compiletype_T compile_type = CT_NONE;
5556
5557 if (func_needs_compiling(ufunc, compile_type))
5558 (void)compile_def_function(ufunc, FALSE, compile_type, NULL);
5559 else
5560 smsg(_("Function %s%s%s does not need compiling"),
5561 cl != NULL ? cl->class_name : (char_u *)"",
5562 cl != NULL ? (char_u *)"." : (char_u *)"",
5563 ufunc->uf_name);
5564 }
5565
5566 /*
5567 * Compile all the :def functions defined in the current script
5568 */
5569 static void
5570 defcompile_funcs_in_script(void)
5571 {
5572 long todo = (long)func_hashtab.ht_used;
5573 int changed = func_hashtab.ht_changed;
5574 hashitem_T *hi;
5575
5576 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi)
5577 {
5578 if (!HASHITEM_EMPTY(hi))
5579 {
5580 --todo;
5581 ufunc_T *ufunc = HI2UF(hi);
5582 if (ufunc->uf_script_ctx.sc_sid == current_sctx.sc_sid
5583 && ufunc->uf_def_status == UF_TO_BE_COMPILED
5584 && (ufunc->uf_flags & FC_DEAD) == 0)
5585 {
5586 (void)compile_def_function(ufunc, FALSE, CT_NONE, NULL);
5587
5588 if (func_hashtab.ht_changed != changed)
5589 {
5590 // a function has been added or removed, need to start
5591 // over
5592 todo = (long)func_hashtab.ht_used;
5593 changed = func_hashtab.ht_changed;
5594 hi = func_hashtab.ht_array;
5595 --hi;
5596 }
5597 }
5598 }
5599 }
5600 }
5601
5602 /*
5549 * :defcompile - compile all :def functions in the current script that need to 5603 * :defcompile - compile all :def functions in the current script that need to
5550 * be compiled or the one specified by the argument. 5604 * be compiled or the one specified by the argument.
5551 * Skips dead functions. Doesn't do profiling. 5605 * Skips dead functions. Doesn't do profiling.
5552 */ 5606 */
5553 void 5607 void
5554 ex_defcompile(exarg_T *eap) 5608 ex_defcompile(exarg_T *eap)
5555 { 5609 {
5556 if (*eap->arg != NUL) 5610 if (*eap->arg != NUL)
5557 { 5611 {
5558 compiletype_T compile_type = CT_NONE; 5612 typval_T tv;
5559 ufunc_T *ufunc = find_func_by_name(eap->arg, &compile_type); 5613
5560 if (ufunc != NULL) 5614 if (is_class_name(eap->arg, &tv))
5561 { 5615 {
5562 if (func_needs_compiling(ufunc, compile_type)) 5616 class_T *cl = tv.vval.v_class;
5563 (void)compile_def_function(ufunc, FALSE, compile_type, NULL); 5617
5564 else 5618 if (cl != NULL)
5565 smsg(_("Function %s does not need compiling"), eap->arg); 5619 defcompile_class(cl);
5620 }
5621 else
5622 {
5623 compiletype_T compile_type = CT_NONE;
5624 ufunc_T *ufunc = find_func_by_name(eap->arg, &compile_type);
5625 if (ufunc != NULL)
5626 defcompile_function(ufunc, NULL);
5566 } 5627 }
5567 } 5628 }
5568 else 5629 else
5569 { 5630 {
5570 long todo = (long)func_hashtab.ht_used; 5631 defcompile_funcs_in_script();
5571 int changed = func_hashtab.ht_changed; 5632
5572 hashitem_T *hi; 5633 // compile all the class defined in the current script
5573 5634 defcompile_classes_in_script();
5574 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi)
5575 {
5576 if (!HASHITEM_EMPTY(hi))
5577 {
5578 --todo;
5579 ufunc_T *ufunc = HI2UF(hi);
5580 if (ufunc->uf_script_ctx.sc_sid == current_sctx.sc_sid
5581 && ufunc->uf_def_status == UF_TO_BE_COMPILED
5582 && (ufunc->uf_flags & FC_DEAD) == 0)
5583 {
5584 (void)compile_def_function(ufunc, FALSE, CT_NONE, NULL);
5585
5586 if (func_hashtab.ht_changed != changed)
5587 {
5588 // a function has been added or removed, need to start
5589 // over
5590 todo = (long)func_hashtab.ht_used;
5591 changed = func_hashtab.ht_changed;
5592 hi = func_hashtab.ht_array;
5593 --hi;
5594 }
5595 }
5596 }
5597 }
5598 } 5635 }
5599 } 5636 }
5600 5637
5601 /* 5638 /*
5602 * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case). 5639 * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case).