summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-07-19 22:19:29 +0200
committerBram Moolenaar <Bram@vim.org>2021-07-19 22:19:29 +0200
commit9bb0dad0d8283c86fddf5b950f4fbb6fb8f12741 (patch)
treee9163a4ab88cd8d8186929f3efc77caac43512bc /src
parent605793500b351ee92483d04b1e03fb8af30dd101 (diff)
patch 8.2.3187: Vim9: popup timer callback is not compiledv8.2.3187
Problem: Vim9: popup timer callback is not compiled. Solution: Compile the callback when creating the timer.
Diffstat (limited to 'src')
-rw-r--r--src/popupwin.c4
-rw-r--r--src/proto/vim9compile.pro1
-rw-r--r--src/version.c2
-rw-r--r--src/vim9compile.c41
4 files changed, 46 insertions, 2 deletions
diff --git a/src/popupwin.c b/src/popupwin.c
index 0f6166aca1..747852735d 100644
--- 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);
diff --git a/src/proto/vim9compile.pro b/src/proto/vim9compile.pro
index 881dddc510..bdefb4ec91 100644
--- a/src/proto/vim9compile.pro
+++ b/src/proto/vim9compile.pro
@@ -11,6 +11,7 @@ char_u *peek_next_line_from_context(cctx_T *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);
diff --git a/src/version.c b/src/version.c
index 0710ce0614..64997fd9ed 100644
--- 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,
diff --git a/src/vim9compile.c b/src/vim9compile.c
index 12dd19823a..97031ef283 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -3671,6 +3671,47 @@ compile_lambda(char_u **arg, cctx_T *cctx)
}
/*
+ * 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.