changeset 25300:e56c8dc1a534 v8.2.3187

patch 8.2.3187: Vim9: popup timer callback is not compiled Commit: https://github.com/vim/vim/commit/9bb0dad0d8283c86fddf5b950f4fbb6fb8f12741 Author: Bram Moolenaar <Bram@vim.org> Date: Mon Jul 19 22:19:29 2021 +0200 patch 8.2.3187: Vim9: popup timer callback is not compiled Problem: Vim9: popup timer callback is not compiled. Solution: Compile the callback when creating the timer.
author Bram Moolenaar <Bram@vim.org>
date Mon, 19 Jul 2021 22:30:04 +0200
parents a1eb85c2e0a5
children fe178301fc04
files src/popupwin.c src/proto/vim9compile.pro src/version.c src/vim9compile.c
diffstat 4 files changed, 46 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/popupwin.c
+++ b/src/popupwin.c
@@ -383,8 +383,8 @@ popup_add_timeout(win_T *wp, int time)
     typval_T	    tv;
 
     vim_snprintf((char *)cbbuf, sizeof(cbbuf),
-				       "{_ -> popup_close(%d)}", wp->w_id);
-    if (get_lambda_tv(&ptr, &tv, FALSE, &EVALARG_EVALUATE) == OK)
+				       "(_) => popup_close(%d)", wp->w_id);
+    if (get_lambda_tv_and_compile(&ptr, &tv, FALSE, &EVALARG_EVALUATE) == OK)
     {
 	wp->w_popup_timer = create_timer(time, 0);
 	wp->w_popup_timer->tr_callback = get_callback(&tv);
--- a/src/proto/vim9compile.pro
+++ b/src/proto/vim9compile.pro
@@ -11,6 +11,7 @@ char_u *peek_next_line_from_context(cctx
 char_u *next_line_from_context(cctx_T *cctx, int skip_comment);
 char_u *to_name_end(char_u *arg, int use_namespace);
 char_u *to_name_const_end(char_u *arg);
+int get_lambda_tv_and_compile(char_u **arg, typval_T *rettv, int types_optional, evalarg_T *evalarg);
 exprtype_T get_compare_type(char_u *p, int *len, int *type_is);
 void error_white_both(char_u *op, int len);
 void fill_exarg_from_cctx(exarg_T *eap, cctx_T *cctx);
--- a/src/version.c
+++ b/src/version.c
@@ -756,6 +756,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    3187,
+/**/
     3186,
 /**/
     3185,
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -3671,6 +3671,47 @@ compile_lambda(char_u **arg, cctx_T *cct
 }
 
 /*
+ * Get a lambda and compile it.  Uses Vim9 syntax.
+ */
+    int
+get_lambda_tv_and_compile(
+	char_u	    **arg,
+	typval_T    *rettv,
+	int	    types_optional,
+	evalarg_T   *evalarg)
+{
+    int		r;
+    ufunc_T	*ufunc;
+    int		save_sc_version = current_sctx.sc_version;
+
+    // Get the funcref in "rettv".
+    current_sctx.sc_version = SCRIPT_VERSION_VIM9;
+    r = get_lambda_tv(arg, rettv, types_optional, evalarg);
+    current_sctx.sc_version = save_sc_version;
+    if (r != OK)
+	return r;
+
+    // "rettv" will now be a partial referencing the function.
+    ufunc = rettv->vval.v_partial->pt_func;
+
+    // Compile it here to get the return type.  The return type is optional,
+    // when it's missing use t_unknown.  This is recognized in
+    // compile_return().
+    if (ufunc->uf_ret_type == NULL || ufunc->uf_ret_type->tt_type == VAR_VOID)
+	ufunc->uf_ret_type = &t_unknown;
+    compile_def_function(ufunc, FALSE, CT_NONE, NULL);
+
+    if (ufunc->uf_def_status == UF_COMPILED)
+    {
+	// The return type will now be known.
+	set_function_type(ufunc);
+	return OK;
+    }
+    clear_tv(rettv);
+    return FAIL;
+}
+
+/*
  * parse a dict: {key: val, [key]: val}
  * "*arg" points to the '{'.
  * ppconst->pp_is_const is set if all item values are a constant.