forked from aniani/vim
patch 8.2.5026: Vim9: a few lines not covered by tests
Problem: Vim9: a few lines not covered by tests. Solution: Delete dead code. Add a few test cases. make "12->func()" work.
This commit is contained in:
@@ -3506,6 +3506,18 @@ one_letter_cmd(char_u *p, cmdidx_T *idx)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return TRUE if "cmd" starts with "123->", a number followed by a method
|
||||||
|
* call.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
number_method(char_u *cmd)
|
||||||
|
{
|
||||||
|
char_u *p = skipdigits(cmd);
|
||||||
|
|
||||||
|
return p > cmd && (p = skipwhite(p))[0] == '-' && p[1] == '>';
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find an Ex command by its name, either built-in or user.
|
* Find an Ex command by its name, either built-in or user.
|
||||||
* Start of the name can be found at eap->cmd.
|
* Start of the name can be found at eap->cmd.
|
||||||
@@ -3716,6 +3728,13 @@ find_ex_command(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 1234->func() is a method call
|
||||||
|
if (number_method(eap->cmd))
|
||||||
|
{
|
||||||
|
eap->cmdidx = CMD_eval;
|
||||||
|
return eap->cmd;
|
||||||
|
}
|
||||||
|
|
||||||
// "g:", "s:" and "l:" are always assumed to be a variable, thus start
|
// "g:", "s:" and "l:" are always assumed to be a variable, thus start
|
||||||
// an expression. A global/substitute/list command needs to use a
|
// an expression. A global/substitute/list command needs to use a
|
||||||
// longer name.
|
// longer name.
|
||||||
|
@@ -17,6 +17,7 @@ void apply_cmdmod(cmdmod_T *cmod);
|
|||||||
void undo_cmdmod(cmdmod_T *cmod);
|
void undo_cmdmod(cmdmod_T *cmod);
|
||||||
int parse_cmd_address(exarg_T *eap, char **errormsg, int silent);
|
int parse_cmd_address(exarg_T *eap, char **errormsg, int silent);
|
||||||
char_u *skip_option_env_lead(char_u *start);
|
char_u *skip_option_env_lead(char_u *start);
|
||||||
|
int number_method(char_u *cmd);
|
||||||
char_u *find_ex_command(exarg_T *eap, int *full, int (*lookup)(char_u *, size_t, int cmd, cctx_T *), cctx_T *cctx);
|
char_u *find_ex_command(exarg_T *eap, int *full, int (*lookup)(char_u *, size_t, int cmd, cctx_T *), cctx_T *cctx);
|
||||||
int modifier_len(char_u *cmd);
|
int modifier_len(char_u *cmd);
|
||||||
int cmd_exists(char_u *name);
|
int cmd_exists(char_u *name);
|
||||||
|
@@ -1121,6 +1121,9 @@ def Test_assignment_dict()
|
|||||||
var dict4: dict<any> = {one: 1, two: '2'}
|
var dict4: dict<any> = {one: 1, two: '2'}
|
||||||
var dict5: dict<blob> = {one: 0z01, two: 0z02}
|
var dict5: dict<blob> = {one: 0z01, two: 0z02}
|
||||||
|
|
||||||
|
# check the type is OK
|
||||||
|
var events: dict<string> = v:event
|
||||||
|
|
||||||
# overwrite
|
# overwrite
|
||||||
dict3['key'] = 'another'
|
dict3['key'] = 'another'
|
||||||
assert_equal(dict3, {key: 'another'})
|
assert_equal(dict3, {key: 'another'})
|
||||||
@@ -2105,6 +2108,32 @@ def Test_var_declaration_fails()
|
|||||||
va foo = 123
|
va foo = 123
|
||||||
END
|
END
|
||||||
v9.CheckDefAndScriptFailure(lines, 'E1065:', 1)
|
v9.CheckDefAndScriptFailure(lines, 'E1065:', 1)
|
||||||
|
|
||||||
|
lines =<< trim END
|
||||||
|
var foo: func(number
|
||||||
|
END
|
||||||
|
v9.CheckDefAndScriptFailure(lines, 'E110:', 1)
|
||||||
|
|
||||||
|
lines =<< trim END
|
||||||
|
var foo: func(number): func(
|
||||||
|
END
|
||||||
|
v9.CheckDefAndScriptFailure(lines, 'E110:', 1)
|
||||||
|
|
||||||
|
for type in ['num_ber',
|
||||||
|
'anys', 'ani',
|
||||||
|
'bools', 'boel',
|
||||||
|
'blobs', 'blub',
|
||||||
|
'channels', 'channol',
|
||||||
|
'dicts', 'duct',
|
||||||
|
'floats', 'floot',
|
||||||
|
'funcs', 'funk',
|
||||||
|
'jobs', 'jop',
|
||||||
|
'lists', 'last'
|
||||||
|
'numbers', 'numbar',
|
||||||
|
'strings', 'strung',
|
||||||
|
'voids', 'viod']
|
||||||
|
v9.CheckDefAndScriptFailure([$'var foo: {type}'], 'E1010:', 1)
|
||||||
|
endfor
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
def Test_var_declaration_inferred()
|
def Test_var_declaration_inferred()
|
||||||
@@ -2118,6 +2147,34 @@ def Test_var_declaration_inferred()
|
|||||||
echo GetList()->extend(['x'])
|
echo GetList()->extend(['x'])
|
||||||
END
|
END
|
||||||
v9.CheckScriptFailure(lines, 'E1013:', 6)
|
v9.CheckScriptFailure(lines, 'E1013:', 6)
|
||||||
|
|
||||||
|
lines =<< trim END
|
||||||
|
vim9script
|
||||||
|
def GetNr(): number
|
||||||
|
return 5
|
||||||
|
enddef
|
||||||
|
def TestOne()
|
||||||
|
var some = [function('len'), GetNr]
|
||||||
|
g:res = typename(some)
|
||||||
|
enddef
|
||||||
|
TestOne()
|
||||||
|
assert_equal('list<func(): number>', g:res)
|
||||||
|
|
||||||
|
def TestTwo()
|
||||||
|
var some = [function('len'), GetNr]
|
||||||
|
g:res = typename(some)
|
||||||
|
enddef
|
||||||
|
TestTwo()
|
||||||
|
assert_equal('list<func(): number>', g:res)
|
||||||
|
unlet g:res
|
||||||
|
|
||||||
|
# FIXME: why is the type different?
|
||||||
|
var first = [function('len'), GetNr]
|
||||||
|
assert_equal('list<func(...): number>', typename(first))
|
||||||
|
var second = [GetNr, function('len')]
|
||||||
|
assert_equal('list<func(...): number>', typename(second))
|
||||||
|
END
|
||||||
|
v9.CheckScriptSuccess(lines)
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
def Test_script_local_in_legacy()
|
def Test_script_local_in_legacy()
|
||||||
|
@@ -4051,6 +4051,63 @@ def Test_too_many_arguments()
|
|||||||
echo [0, 1, 2]->map((_) => 123)
|
echo [0, 1, 2]->map((_) => 123)
|
||||||
END
|
END
|
||||||
v9.CheckDefAndScriptFailure(lines, ['E176', 'E1106: One argument too many'], 1)
|
v9.CheckDefAndScriptFailure(lines, ['E176', 'E1106: One argument too many'], 1)
|
||||||
|
|
||||||
|
lines =<< trim END
|
||||||
|
vim9script
|
||||||
|
def OneArgument(arg: string)
|
||||||
|
echo arg
|
||||||
|
enddef
|
||||||
|
var Ref = OneArgument
|
||||||
|
Ref('a', 'b')
|
||||||
|
END
|
||||||
|
v9.CheckScriptFailure(lines, 'E118:')
|
||||||
|
enddef
|
||||||
|
|
||||||
|
def Test_funcref_with_base()
|
||||||
|
var lines =<< trim END
|
||||||
|
vim9script
|
||||||
|
def TwoArguments(str: string, nr: number)
|
||||||
|
echo str nr
|
||||||
|
enddef
|
||||||
|
var Ref = TwoArguments
|
||||||
|
Ref('a', 12)
|
||||||
|
'b'->Ref(34)
|
||||||
|
END
|
||||||
|
v9.CheckScriptSuccess(lines)
|
||||||
|
|
||||||
|
lines =<< trim END
|
||||||
|
vim9script
|
||||||
|
def TwoArguments(str: string, nr: number)
|
||||||
|
echo str nr
|
||||||
|
enddef
|
||||||
|
var Ref = TwoArguments
|
||||||
|
'a'->Ref('b')
|
||||||
|
END
|
||||||
|
v9.CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected number but got string', 6)
|
||||||
|
|
||||||
|
lines =<< trim END
|
||||||
|
vim9script
|
||||||
|
def TwoArguments(str: string, nr: number)
|
||||||
|
echo str nr
|
||||||
|
enddef
|
||||||
|
var Ref = TwoArguments
|
||||||
|
123->Ref(456)
|
||||||
|
END
|
||||||
|
v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
|
||||||
|
|
||||||
|
lines =<< trim END
|
||||||
|
vim9script
|
||||||
|
def TwoArguments(nr: number, str: string)
|
||||||
|
echo str nr
|
||||||
|
enddef
|
||||||
|
var Ref = TwoArguments
|
||||||
|
123->Ref('b')
|
||||||
|
def AndNowCompiled()
|
||||||
|
456->Ref('x')
|
||||||
|
enddef
|
||||||
|
AndNowCompiled()
|
||||||
|
END
|
||||||
|
v9.CheckScriptSuccess(lines)
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
def Test_closing_brace_at_start_of_line()
|
def Test_closing_brace_at_start_of_line()
|
||||||
|
@@ -734,6 +734,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 */
|
||||||
|
/**/
|
||||||
|
5026,
|
||||||
/**/
|
/**/
|
||||||
5025,
|
5025,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -3001,6 +3001,7 @@ compile_def_function(
|
|||||||
* 0z1234->func() should not be confused with a zero line number
|
* 0z1234->func() should not be confused with a zero line number
|
||||||
* "++nr" and "--nr" are eval commands
|
* "++nr" and "--nr" are eval commands
|
||||||
* in "$ENV->func()" the "$" is not a range
|
* in "$ENV->func()" the "$" is not a range
|
||||||
|
* "123->func()" is a method call
|
||||||
*/
|
*/
|
||||||
cmd = ea.cmd;
|
cmd = ea.cmd;
|
||||||
if ((*cmd != '$' || starts_with_colon)
|
if ((*cmd != '$' || starts_with_colon)
|
||||||
@@ -3008,7 +3009,8 @@ compile_def_function(
|
|||||||
|| !(*cmd == '\''
|
|| !(*cmd == '\''
|
||||||
|| (cmd[0] == '0' && cmd[1] == 'z')
|
|| (cmd[0] == '0' && cmd[1] == 'z')
|
||||||
|| (cmd[0] != NUL && cmd[0] == cmd[1]
|
|| (cmd[0] != NUL && cmd[0] == cmd[1]
|
||||||
&& (*cmd == '+' || *cmd == '-')))))
|
&& (*cmd == '+' || *cmd == '-'))
|
||||||
|
|| number_method(cmd))))
|
||||||
{
|
{
|
||||||
ea.cmd = skip_range(ea.cmd, TRUE, NULL);
|
ea.cmd = skip_range(ea.cmd, TRUE, NULL);
|
||||||
if (ea.cmd > cmd)
|
if (ea.cmd > cmd)
|
||||||
|
@@ -244,15 +244,12 @@ alloc_func_type(type_T *ret_type, int argcount, garray_T *type_gap)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Get a function type, based on the return type "ret_type".
|
* Get a function type, based on the return type "ret_type".
|
||||||
* If "argcount" is -1 or 0 a predefined type can be used.
|
* "argcount" must be -1 or 0, a predefined type can be used.
|
||||||
* If "argcount" > 0 always create a new type, so that arguments can be added.
|
|
||||||
*/
|
*/
|
||||||
type_T *
|
type_T *
|
||||||
get_func_type(type_T *ret_type, int argcount, garray_T *type_gap)
|
get_func_type(type_T *ret_type, int argcount, garray_T *type_gap)
|
||||||
{
|
{
|
||||||
// recognize commonly used types
|
// recognize commonly used types
|
||||||
if (argcount <= 0)
|
|
||||||
{
|
|
||||||
if (ret_type == &t_unknown || ret_type == NULL)
|
if (ret_type == &t_unknown || ret_type == NULL)
|
||||||
{
|
{
|
||||||
// (argcount == 0) is not possible
|
// (argcount == 0) is not possible
|
||||||
@@ -286,7 +283,6 @@ get_func_type(type_T *ret_type, int argcount, garray_T *type_gap)
|
|||||||
else
|
else
|
||||||
return &t_func_string;
|
return &t_func_string;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return alloc_func_type(ret_type, argcount, type_gap);
|
return alloc_func_type(ret_type, argcount, type_gap);
|
||||||
}
|
}
|
||||||
@@ -541,7 +537,7 @@ typval2type_vimvar(typval_T *tv, garray_T *type_gap)
|
|||||||
{
|
{
|
||||||
if (tv->v_type == VAR_LIST) // e.g. for v:oldfiles
|
if (tv->v_type == VAR_LIST) // e.g. for v:oldfiles
|
||||||
return &t_list_string;
|
return &t_list_string;
|
||||||
if (tv->v_type == VAR_DICT) // e.g. for v:completed_item
|
if (tv->v_type == VAR_DICT) // e.g. for v:event
|
||||||
return &t_dict_any;
|
return &t_dict_any;
|
||||||
return typval2type(tv, get_copyID(), type_gap, TVTT_DO_MEMBER);
|
return typval2type(tv, get_copyID(), type_gap, TVTT_DO_MEMBER);
|
||||||
}
|
}
|
||||||
@@ -1441,6 +1437,7 @@ vartype_name(vartype_T type)
|
|||||||
type_name(type_T *type, char **tofree)
|
type_name(type_T *type, char **tofree)
|
||||||
{
|
{
|
||||||
char *name;
|
char *name;
|
||||||
|
char *arg_free = NULL;
|
||||||
|
|
||||||
*tofree = NULL;
|
*tofree = NULL;
|
||||||
if (type == NULL)
|
if (type == NULL)
|
||||||
@@ -1469,13 +1466,12 @@ type_name(type_T *type, char **tofree)
|
|||||||
|
|
||||||
ga_init2(&ga, 1, 100);
|
ga_init2(&ga, 1, 100);
|
||||||
if (ga_grow(&ga, 20) == FAIL)
|
if (ga_grow(&ga, 20) == FAIL)
|
||||||
return "[unknown]";
|
goto failed;
|
||||||
STRCPY(ga.ga_data, "func(");
|
STRCPY(ga.ga_data, "func(");
|
||||||
ga.ga_len += 5;
|
ga.ga_len += 5;
|
||||||
|
|
||||||
for (i = 0; i < type->tt_argcount; ++i)
|
for (i = 0; i < type->tt_argcount; ++i)
|
||||||
{
|
{
|
||||||
char *arg_free = NULL;
|
|
||||||
char *arg_type;
|
char *arg_type;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
@@ -1490,17 +1486,13 @@ type_name(type_T *type, char **tofree)
|
|||||||
}
|
}
|
||||||
len = (int)STRLEN(arg_type);
|
len = (int)STRLEN(arg_type);
|
||||||
if (ga_grow(&ga, len + 8) == FAIL)
|
if (ga_grow(&ga, len + 8) == FAIL)
|
||||||
{
|
goto failed;
|
||||||
vim_free(arg_free);
|
|
||||||
ga_clear(&ga);
|
|
||||||
return "[unknown]";
|
|
||||||
}
|
|
||||||
if (varargs && i == type->tt_argcount - 1)
|
if (varargs && i == type->tt_argcount - 1)
|
||||||
ga_concat(&ga, (char_u *)"...");
|
ga_concat(&ga, (char_u *)"...");
|
||||||
else if (i >= type->tt_min_argcount)
|
else if (i >= type->tt_min_argcount)
|
||||||
*((char *)ga.ga_data + ga.ga_len++) = '?';
|
*((char *)ga.ga_data + ga.ga_len++) = '?';
|
||||||
ga_concat(&ga, (char_u *)arg_type);
|
ga_concat(&ga, (char_u *)arg_type);
|
||||||
vim_free(arg_free);
|
VIM_CLEAR(arg_free);
|
||||||
}
|
}
|
||||||
if (type->tt_argcount < 0)
|
if (type->tt_argcount < 0)
|
||||||
// any number of arguments
|
// any number of arguments
|
||||||
@@ -1516,17 +1508,18 @@ type_name(type_T *type, char **tofree)
|
|||||||
|
|
||||||
len = (int)STRLEN(ret_name) + 4;
|
len = (int)STRLEN(ret_name) + 4;
|
||||||
if (ga_grow(&ga, len) == FAIL)
|
if (ga_grow(&ga, len) == FAIL)
|
||||||
{
|
goto failed;
|
||||||
vim_free(ret_free);
|
|
||||||
ga_clear(&ga);
|
|
||||||
return "[unknown]";
|
|
||||||
}
|
|
||||||
STRCPY((char *)ga.ga_data + ga.ga_len, "): ");
|
STRCPY((char *)ga.ga_data + ga.ga_len, "): ");
|
||||||
STRCPY((char *)ga.ga_data + ga.ga_len + 3, ret_name);
|
STRCPY((char *)ga.ga_data + ga.ga_len + 3, ret_name);
|
||||||
vim_free(ret_free);
|
vim_free(ret_free);
|
||||||
}
|
}
|
||||||
*tofree = ga.ga_data;
|
*tofree = ga.ga_data;
|
||||||
return ga.ga_data;
|
return ga.ga_data;
|
||||||
|
|
||||||
|
failed:
|
||||||
|
vim_free(arg_free);
|
||||||
|
ga_clear(&ga);
|
||||||
|
return "[unknown]";
|
||||||
}
|
}
|
||||||
|
|
||||||
return name;
|
return name;
|
||||||
|
Reference in New Issue
Block a user