diff src/userfunc.c @ 23338:9c5275b1c763 v8.2.2212

patch 8.2.2212: Vim9: lambda with => does not work at the script level Commit: https://github.com/vim/vim/commit/c754b4cc98253e1935d3ea5790bc60869c7bc091 Author: Bram Moolenaar <Bram@vim.org> Date: Fri Dec 25 15:24:23 2020 +0100 patch 8.2.2212: Vim9: lambda with => does not work at the script level Problem: Vim9: lambda with => does not work at the script level. Solution: Make it work.
author Bram Moolenaar <Bram@vim.org>
date Fri, 25 Dec 2020 15:30:04 +0100
parents cdb706d5c43d
children 8e0d6f355a5a
line wrap: on
line diff
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -461,21 +461,35 @@ register_cfunc(cfunc_T cb, cfunc_free_T 
 /*
  * Skip over "->" or "=>" after the arguments of a lambda.
  * If ": type" is found make "ret_type" point to "type".
+ * If "white_error" is not NULL check for correct use of white space and set
+ * "white_error" to TRUE if there is an error.
  * Return NULL if no valid arrow found.
  */
     static char_u *
-skip_arrow(char_u *start, int equal_arrow, char_u **ret_type)
+skip_arrow(
+	char_u	*start,
+	int	equal_arrow,
+	char_u	**ret_type,
+	int	*white_error)
 {
-    char_u *s = start;
+    char_u  *s = start;
+    char_u  *bef = start - 2; // "start" points to > of ->
 
     if (equal_arrow)
     {
 	if (*s == ':')
 	{
+	    if (white_error != NULL && !VIM_ISWHITE(s[1]))
+	    {
+		*white_error = TRUE;
+		semsg(_(e_white_space_required_after_str), ":");
+		return NULL;
+	    }
 	    s = skipwhite(s + 1);
 	    *ret_type = s;
 	    s = skip_type(s, TRUE);
 	}
+	bef = s;
 	s = skipwhite(s);
 	if (*s != '=')
 	    return NULL;
@@ -483,6 +497,14 @@ skip_arrow(char_u *start, int equal_arro
     }
     if (*s != '>')
 	return NULL;
+    if (white_error != NULL && ((!VIM_ISWHITE(*bef) && *bef != '{')
+		|| !IS_WHITE_OR_NUL(s[1])))
+    {
+	*white_error = TRUE;
+	semsg(_(e_white_space_required_before_and_after_str),
+						    equal_arrow ? "=>" : "->");
+	return NULL;
+    }
     return skipwhite(s + 1);
 }
 
@@ -516,6 +538,7 @@ get_lambda_tv(
     int		eval_lavars = FALSE;
     char_u	*tofree = NULL;
     int		equal_arrow = **arg == '(';
+    int		white_error = FALSE;
 
     if (equal_arrow && !in_vim9script())
 	return NOTDONE;
@@ -529,7 +552,7 @@ get_lambda_tv(
     ret = get_function_args(&s, equal_arrow ? ')' : '-', NULL,
 	    types_optional ? &argtypes : NULL, types_optional,
 						 NULL, NULL, TRUE, NULL, NULL);
-    if (ret == FAIL || skip_arrow(s, equal_arrow, &ret_type) == NULL)
+    if (ret == FAIL || skip_arrow(s, equal_arrow, &ret_type, NULL) == NULL)
     {
 	if (types_optional)
 	    ga_clear_strings(&argtypes);
@@ -546,12 +569,14 @@ get_lambda_tv(
 	    types_optional ? &argtypes : NULL, types_optional,
 					    &varargs, NULL, FALSE, NULL, NULL);
     if (ret == FAIL
-		  || (*arg = skip_arrow(*arg, equal_arrow, &ret_type)) == NULL)
+		  || (s = skip_arrow(*arg, equal_arrow, &ret_type,
+							&white_error)) == NULL)
     {
 	if (types_optional)
 	    ga_clear_strings(&argtypes);
-	return NOTDONE;
+	return white_error ? FAIL : NOTDONE;
     }
+    *arg = s;
 
     // Set up a flag for checking local variables and arguments.
     if (evaluate)
@@ -647,8 +672,6 @@ get_lambda_tv(
 	    if (register_closure(fp) == FAIL)
 		goto errret;
 	}
-	else
-	    fp->uf_scoped = NULL;
 
 #ifdef FEAT_PROFILE
 	if (prof_def_func())