]> granicus.if.org Git - vim/commitdiff
patch 8.2.3705: cannot pass a lambda name to function() or funcref() v8.2.3705
authorBram Moolenaar <Bram@vim.org>
Tue, 30 Nov 2021 18:25:08 +0000 (18:25 +0000)
committerBram Moolenaar <Bram@vim.org>
Tue, 30 Nov 2021 18:25:08 +0000 (18:25 +0000)
Problem:    Cannot pass a lambda name to function() or funcref(). (Yegappan
            Lakshmanan)
Solution:   Handle a lambda name differently.

src/evalfunc.c
src/proto/userfunc.pro
src/testdir/test_expr.vim
src/userfunc.c
src/version.c

index e04052b8acc251514286d7472abbabbb0d00dff4..d0b80bea837992762f51bb4bc908223fd782fd4f 100644 (file)
@@ -3955,9 +3955,8 @@ common_function(typval_T *argvars, typval_T *rettv, int is_funcref)
     if ((use_string && vim_strchr(s, AUTOLOAD_CHAR) == NULL) || is_funcref)
     {
        name = s;
-       trans_name = trans_function_name(&name, &is_global, FALSE,
-            TFN_INT | TFN_QUIET | TFN_NO_AUTOLOAD | TFN_NO_DEREF,
-                                                            NULL, NULL, NULL);
+       trans_name = save_function_name(&name, &is_global, FALSE,
+                  TFN_INT | TFN_QUIET | TFN_NO_AUTOLOAD | TFN_NO_DEREF, NULL);
        if (*name != NUL)
            s = NULL;
     }
index 08dedae0a69c21dd33b4e1b3ed14bf35c1f41e13..dcc5b34d0552e94031956fb337a0b369eb968f2e 100644 (file)
@@ -33,6 +33,7 @@ int call_func(char_u *funcname, int len, typval_T *rettv, int argcount_in, typva
 char_u *printable_func_name(ufunc_T *fp);
 char_u *trans_function_name(char_u **pp, int *is_global, int skip, int flags, funcdict_T *fdp, partial_T **partial, type_T **type);
 char_u *untrans_function_name(char_u *name);
+char_u *save_function_name(char_u **name, int *is_global, int skip, int flags, funcdict_T *fudi);
 void list_functions(regmatch_T *regmatch);
 ufunc_T *define_function(exarg_T *eap, char_u *name_arg);
 void ex_function(exarg_T *eap);
index 323ce2626dc034ba0c90303d03bb49e194e7c049..46d718612509ac4d114c86240fc3c0cac9832652 100644 (file)
@@ -547,6 +547,13 @@ func Test_function_with_funcref()
   call assert_fails("call function('foo()')", 'E475:')
   call assert_fails("call function('foo()')", 'foo()')
   call assert_fails("function('')", 'E129:')
+
+  let Len = {s -> strlen(s)}
+  call assert_equal(6, Len('foobar'))
+  let name = string(Len)
+  " can evaluate "function('<lambda>99')"
+  call execute('let Ref = ' .. name)
+  call assert_equal(4, Ref('text'))
 endfunc
 
 func Test_funcref()
index c961115e0418b787729b00e010a760f7a7ad801f..3edbf891efd7476e999a47a162fb260361f991b2 100644 (file)
@@ -3810,6 +3810,36 @@ untrans_function_name(char_u *name)
     return NULL;
 }
 
+/*
+ * Call trans_function_name(), except that a lambda is returned as-is.
+ * Returns the name in allocated memory.
+ */
+    char_u *
+save_function_name(
+       char_u      **name,
+       int         *is_global,
+       int         skip,
+       int         flags,
+       funcdict_T  *fudi)
+{
+    char_u *p = *name;
+    char_u *saved;
+
+    if (STRNCMP(p, "<lambda>", 8) == 0)
+    {
+       p += 8;
+       (void)getdigits(&p);
+       saved = vim_strnsave(*name, p - *name);
+       if (fudi != NULL)
+           CLEAR_POINTER(fudi);
+    }
+    else
+       saved = trans_function_name(&p, is_global, skip,
+                                                     flags, fudi, NULL, NULL);
+    *name = p;
+    return saved;
+}
+
 /*
  * List functions.  When "regmatch" is NULL all of then.
  * Otherwise functions matching "regmatch".
@@ -3950,16 +3980,8 @@ define_function(exarg_T *eap, char_u *name_arg)
     }
     else
     {
-       if (STRNCMP(p, "<lambda>", 8) == 0)
-       {
-           p += 8;
-           (void)getdigits(&p);
-           name = vim_strnsave(eap->arg, p - eap->arg);
-           CLEAR_FIELD(fudi);
-       }
-       else
-           name = trans_function_name(&p, &is_global, eap->skip,
-                                          TFN_NO_AUTOLOAD, &fudi, NULL, NULL);
+       name = save_function_name(&p, &is_global, eap->skip,
+                                                      TFN_NO_AUTOLOAD, &fudi);
        paren = (vim_strchr(p, '(') != NULL);
        if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip)
        {
index 32efc5c83f86585e9925731be0179da6ca68bc0e..570cd2174ce8c5cb3d5047599a9bd5dbd30d84b0 100644 (file)
@@ -753,6 +753,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3705,
 /**/
     3704,
 /**/