patch 9.1.1617: Vim9: some error messages can be improved

Problem:  Vim9: some error messages can be improved
Solution: Improve error messages when parsing generic function type
          arguments (Yegappan Lakshmanan).

closes: #17957

Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Yegappan Lakshmanan
2025-08-10 09:15:03 +02:00
committed by Christian Brabandt
parent 57eb1d496b
commit 1434ea03b1
4 changed files with 42 additions and 17 deletions

View File

@ -3715,9 +3715,9 @@ find_ex_command(
// "&option" can be followed by "->" or "=", check below // "&option" can be followed by "->" or "=", check below
} }
if (*p == '<' && vim9) if (vim9 && *p == '<')
{ {
// generic function // generic function type args
if (skip_generic_func_type_args(&p) == FAIL) if (skip_generic_func_type_args(&p) == FAIL)
{ {
eap->cmdidx = CMD_SIZE; eap->cmdidx = CMD_SIZE;

View File

@ -387,6 +387,14 @@ def Test_generic_func_invoke_whitespace_error()
Fn<number,string>() Fn<number,string>()
END END
v9.CheckSourceFailure(lines, "E1069: White space required after ',': <number,string>()", 4) v9.CheckSourceFailure(lines, "E1069: White space required after ',': <number,string>()", 4)
lines =<< trim END
vim9script
def Fn<A>()
enddef
Fn<number> ()
END
v9.CheckSourceFailure(lines, "E1202: No white space allowed after '>': <number> ()", 4)
enddef enddef
def Test_generic_func_typename() def Test_generic_func_typename()
@ -2211,7 +2219,7 @@ def Test_generic_disassemble_generic_obj_method()
endclass endclass
disassemble Foo.Fn<number, dict<number> disassemble Foo.Fn<number, dict<number>
END END
v9.CheckScriptFailure(lines, 'E1553: Missing comma after type in generic function: <number, dict<number>', 6) v9.CheckScriptFailure(lines, "E1554: Missing '>' in generic function: Fn<number, dict<number>", 6)
lines =<< trim END lines =<< trim END
vim9script vim9script
@ -2229,7 +2237,7 @@ def Test_generic_disassemble_generic_obj_method()
endclass endclass
disassemble Foo.Fn<number, disassemble Foo.Fn<number,
END END
v9.CheckScriptFailure(lines, "E1069: White space required after ','", 6) v9.CheckScriptFailure(lines, "E1554: Missing '>' in generic function: Fn<number,", 6)
lines =<< trim END lines =<< trim END
vim9script vim9script
@ -2239,7 +2247,7 @@ def Test_generic_disassemble_generic_obj_method()
endclass endclass
disassemble Foo.Fn< disassemble Foo.Fn<
END END
v9.CheckScriptFailure(lines, 'E475: Invalid argument: Foo.Fn<', 6) v9.CheckScriptFailure(lines, "E1554: Missing '>' in generic function: Fn<", 6)
lines =<< trim END lines =<< trim END
vim9script vim9script
@ -2339,7 +2347,7 @@ def Test_generic_disassemble_generic_class_method()
endclass endclass
disassemble Foo.Fn<number, dict<number> disassemble Foo.Fn<number, dict<number>
END END
v9.CheckScriptFailure(lines, 'E1553: Missing comma after type in generic function: <number, dict<number>', 6) v9.CheckScriptFailure(lines, "E1554: Missing '>' in generic function: Fn<number, dict<number>", 6)
lines =<< trim END lines =<< trim END
vim9script vim9script
@ -2349,7 +2357,7 @@ def Test_generic_disassemble_generic_class_method()
endclass endclass
disassemble Foo.Fn<number, disassemble Foo.Fn<number,
END END
v9.CheckScriptFailure(lines, "E1069: White space required after ','", 6) v9.CheckScriptFailure(lines, "E1554: Missing '>' in generic function: Fn<number,", 6)
lines =<< trim END lines =<< trim END
vim9script vim9script
@ -2359,7 +2367,7 @@ def Test_generic_disassemble_generic_class_method()
endclass endclass
disassemble Foo.Fn< disassemble Foo.Fn<
END END
v9.CheckScriptFailure(lines, 'E475: Invalid argument: Foo.Fn<', 6) v9.CheckScriptFailure(lines, "E1554: Missing '>' in generic function: Fn<", 6)
lines =<< trim END lines =<< trim END
vim9script vim9script

View File

@ -719,6 +719,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1617,
/**/ /**/
1616, 1616,
/**/ /**/

View File

@ -149,6 +149,14 @@ generic_func_find_close_bracket(char_u *start)
return NULL; return NULL;
} }
if (VIM_ISWHITE(*(p + 1)) && *skipwhite(p + 1) == '(')
{
// white space not allowed between '>' and '('
semsg(_(e_no_white_space_allowed_after_str_str), ">", start);
return NULL;
}
if (type_count == 0) if (type_count == 0)
{ {
semsg(_(e_empty_type_list_for_generic_function_str), start); semsg(_(e_empty_type_list_for_generic_function_str), start);
@ -326,28 +334,35 @@ parse_generic_func_type_args(
p = skipwhite(p); p = skipwhite(p);
if (*p == NUL || *p == '>')
break;
// after a type, expect ',' or '>' // after a type, expect ',' or '>'
if (*p != ',' && *p != '>') if (*p != ',')
{ {
semsg(_(e_missing_comma_in_generic_function_str), start); semsg(_(e_missing_comma_in_generic_function_str), start);
return NULL; return NULL;
} }
// if there's a comma, require whitespace after it and skip it if (*(p + 1) == NUL)
if (*p == ',') break;
// Require whitespace after a comma and skip it
if (!VIM_ISWHITE(*(p + 1)))
{ {
if (!VIM_ISWHITE(*(p + 1))) semsg(_(e_white_space_required_after_str_str), ",", p);
{ return NULL;
semsg(_(e_white_space_required_after_str_str), ",", p);
return NULL;
}
p++;
} }
p++;
} }
// ensure the list of types ends in a closing '>' // ensure the list of types ends in a closing '>'
if (*p != '>') if (*p != '>')
{
semsg(_(e_missing_closing_angle_bracket_in_generic_function_str),
func_name);
return NULL; return NULL;
}
// no whitespace allowed before '>' // no whitespace allowed before '>'
if (VIM_ISWHITE(*(p - 1))) if (VIM_ISWHITE(*(p - 1)))