forked from aniani/vim
patch 9.0.1928: Vim9: constructor type checking bug
Problem: Vim9: constructor type checking bug Solution: Fix class constructor regression closes: #13102 closes: #13113 Signed-off-by: Christian Brabandt <cb@256bit.org> Co-authored-by: h-east <h.east.727@gmail.com>
This commit is contained in:
committed by
Christian Brabandt
parent
ceee7a808c
commit
b895b0fabc
@@ -65,6 +65,7 @@ one_function_arg(
|
||||
garray_T *newargs,
|
||||
garray_T *argtypes,
|
||||
int types_optional,
|
||||
garray_T *arg_objm,
|
||||
evalarg_T *evalarg,
|
||||
exarg_T *eap,
|
||||
int is_vararg,
|
||||
@@ -136,7 +137,8 @@ one_function_arg(
|
||||
}
|
||||
|
||||
// get any type from "arg: type"
|
||||
if (argtypes != NULL && (skip || ga_grow(argtypes, 1) == OK))
|
||||
if (argtypes != NULL && (skip || ga_grow(argtypes, 1) == OK)
|
||||
&& arg_objm != NULL && (skip || ga_grow(arg_objm, 1) == OK))
|
||||
{
|
||||
char_u *type = NULL;
|
||||
|
||||
@@ -172,6 +174,7 @@ one_function_arg(
|
||||
type = vim_strsave((char_u *)
|
||||
(is_vararg ? "list<any>" : "any"));
|
||||
((char_u **)argtypes->ga_data)[argtypes->ga_len++] = type;
|
||||
((int8_T *)arg_objm->ga_data)[arg_objm->ga_len++] = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,6 +224,7 @@ get_function_args(
|
||||
garray_T *newargs,
|
||||
garray_T *argtypes, // NULL unless using :def
|
||||
int types_optional, // types optional if "argtypes" is not NULL
|
||||
garray_T *arg_objm, // NULL unless using :def
|
||||
evalarg_T *evalarg, // context or NULL
|
||||
int *varargs,
|
||||
garray_T *default_args,
|
||||
@@ -241,6 +245,8 @@ get_function_args(
|
||||
ga_init2(newargs, sizeof(char_u *), 3);
|
||||
if (argtypes != NULL)
|
||||
ga_init2(argtypes, sizeof(char_u *), 3);
|
||||
if (arg_objm != NULL)
|
||||
ga_init2(arg_objm, sizeof(int8_T), 3);
|
||||
if (!skip && default_args != NULL)
|
||||
ga_init2(default_args, sizeof(char_u *), 3);
|
||||
|
||||
@@ -295,7 +301,7 @@ get_function_args(
|
||||
|
||||
arg = p;
|
||||
p = one_function_arg(p, newargs, argtypes, types_optional,
|
||||
evalarg, eap, TRUE, skip);
|
||||
arg_objm, evalarg, eap, TRUE, skip);
|
||||
if (p == arg)
|
||||
break;
|
||||
if (*skipwhite(p) == '=')
|
||||
@@ -350,11 +356,13 @@ get_function_args(
|
||||
vim_strnsave(arg, argend - arg);
|
||||
newargs->ga_len++;
|
||||
|
||||
if (argtypes != NULL && ga_grow(argtypes, 1) == OK)
|
||||
if (argtypes != NULL && ga_grow(argtypes, 1) == OK
|
||||
&& arg_objm != NULL && ga_grow(arg_objm, 1) == OK)
|
||||
{
|
||||
// TODO: use the actual type
|
||||
((char_u **)argtypes->ga_data)[argtypes->ga_len++] =
|
||||
vim_strsave((char_u *)"any");
|
||||
((int8_T *)arg_objm->ga_data)[arg_objm->ga_len++] = TRUE;
|
||||
|
||||
// Add a line to the function body for the assignment.
|
||||
if (ga_grow(newlines, 1) == OK)
|
||||
@@ -391,7 +399,7 @@ get_function_args(
|
||||
|
||||
arg = p;
|
||||
p = one_function_arg(p, newargs, argtypes, types_optional,
|
||||
evalarg, eap, FALSE, skip);
|
||||
arg_objm, evalarg, eap, FALSE, skip);
|
||||
if (p == arg)
|
||||
break;
|
||||
|
||||
@@ -490,7 +498,13 @@ err_ret:
|
||||
* Return OK or FAIL.
|
||||
*/
|
||||
static int
|
||||
parse_argument_types(ufunc_T *fp, garray_T *argtypes, int varargs)
|
||||
parse_argument_types(
|
||||
ufunc_T *fp,
|
||||
garray_T *argtypes,
|
||||
int varargs,
|
||||
garray_T *arg_objm,
|
||||
ocmember_T *obj_members,
|
||||
int obj_member_count)
|
||||
{
|
||||
int len = 0;
|
||||
|
||||
@@ -516,7 +530,24 @@ parse_argument_types(ufunc_T *fp, garray_T *argtypes, int varargs)
|
||||
// will get the type from the default value
|
||||
type = &t_unknown;
|
||||
else
|
||||
type = parse_type(&p, &fp->uf_type_list, TRUE);
|
||||
{
|
||||
if (arg_objm != NULL && ((int8_T *)arg_objm->ga_data)[i])
|
||||
{
|
||||
char_u *aname = ((char_u **)fp->uf_args.ga_data)[i];
|
||||
|
||||
type = &t_any;
|
||||
for (int om = 0; om < obj_member_count; ++om)
|
||||
{
|
||||
if (STRCMP(aname, obj_members[om].ocm_name) == 0)
|
||||
{
|
||||
type = obj_members[om].ocm_type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
type = parse_type(&p, &fp->uf_type_list, TRUE);
|
||||
}
|
||||
if (type == NULL)
|
||||
return FAIL;
|
||||
fp->uf_arg_types[i] = type;
|
||||
@@ -1395,7 +1426,7 @@ lambda_function_body(
|
||||
SOURCING_LNUM = sourcing_lnum_top;
|
||||
|
||||
// parse argument types
|
||||
if (parse_argument_types(ufunc, argtypes, varargs) == FAIL)
|
||||
if (parse_argument_types(ufunc, argtypes, varargs, NULL, NULL, 0) == FAIL)
|
||||
{
|
||||
SOURCING_LNUM = lnum_save;
|
||||
goto erret;
|
||||
@@ -1464,6 +1495,7 @@ get_lambda_tv(
|
||||
garray_T *pnewargs;
|
||||
garray_T argtypes;
|
||||
garray_T default_args;
|
||||
garray_T arg_objm;
|
||||
ufunc_T *fp = NULL;
|
||||
partial_T *pt = NULL;
|
||||
int varargs;
|
||||
@@ -1490,12 +1522,16 @@ get_lambda_tv(
|
||||
// be found after the arguments.
|
||||
s = *arg + 1;
|
||||
ret = get_function_args(&s, equal_arrow ? ')' : '-', NULL,
|
||||
types_optional ? &argtypes : NULL, types_optional, evalarg,
|
||||
NULL, &default_args, TRUE, NULL, FALSE, NULL, NULL);
|
||||
types_optional ? &argtypes : NULL, types_optional,
|
||||
types_optional ? &arg_objm : NULL, evalarg,
|
||||
NULL, &default_args, TRUE, NULL, FALSE, NULL, NULL);
|
||||
if (ret == FAIL || skip_arrow(s, equal_arrow, &ret_type, NULL) == NULL)
|
||||
{
|
||||
if (types_optional)
|
||||
{
|
||||
ga_clear_strings(&argtypes);
|
||||
ga_clear(&arg_objm);
|
||||
}
|
||||
return called_emsg == called_emsg_start ? NOTDONE : FAIL;
|
||||
}
|
||||
|
||||
@@ -1506,7 +1542,8 @@ get_lambda_tv(
|
||||
pnewargs = NULL;
|
||||
*arg += 1;
|
||||
ret = get_function_args(arg, equal_arrow ? ')' : '-', pnewargs,
|
||||
types_optional ? &argtypes : NULL, types_optional, evalarg,
|
||||
types_optional ? &argtypes : NULL, types_optional,
|
||||
types_optional ? &arg_objm : NULL, evalarg,
|
||||
&varargs, &default_args,
|
||||
FALSE, NULL, FALSE, NULL, NULL);
|
||||
if (ret == FAIL
|
||||
@@ -1514,7 +1551,10 @@ get_lambda_tv(
|
||||
equal_arrow || vim9script ? &white_error : NULL)) == NULL)
|
||||
{
|
||||
if (types_optional)
|
||||
{
|
||||
ga_clear_strings(&argtypes);
|
||||
ga_clear(&arg_objm);
|
||||
}
|
||||
ga_clear_strings(&newargs);
|
||||
return white_error ? FAIL : NOTDONE;
|
||||
}
|
||||
@@ -1631,7 +1671,7 @@ get_lambda_tv(
|
||||
if (types_optional)
|
||||
{
|
||||
if (parse_argument_types(fp, &argtypes,
|
||||
vim9script && varargs) == FAIL)
|
||||
vim9script && varargs, NULL, NULL, 0) == FAIL)
|
||||
goto errret;
|
||||
if (ret_type != NULL)
|
||||
{
|
||||
@@ -4591,7 +4631,9 @@ define_function(
|
||||
exarg_T *eap,
|
||||
char_u *name_arg,
|
||||
garray_T *lines_to_free,
|
||||
int class_flags)
|
||||
int class_flags,
|
||||
ocmember_T *obj_members,
|
||||
int obj_member_count)
|
||||
{
|
||||
int j;
|
||||
int c;
|
||||
@@ -4604,6 +4646,7 @@ define_function(
|
||||
char_u *line_arg = NULL;
|
||||
garray_T newargs;
|
||||
garray_T argtypes;
|
||||
garray_T arg_objm;
|
||||
garray_T default_args;
|
||||
garray_T newlines;
|
||||
int varargs = FALSE;
|
||||
@@ -4662,6 +4705,7 @@ define_function(
|
||||
|
||||
ga_init(&newargs);
|
||||
ga_init(&argtypes);
|
||||
ga_init(&arg_objm);
|
||||
ga_init(&default_args);
|
||||
|
||||
/*
|
||||
@@ -4909,6 +4953,7 @@ define_function(
|
||||
++p;
|
||||
if (get_function_args(&p, ')', &newargs,
|
||||
eap->cmdidx == CMD_def ? &argtypes : NULL, FALSE,
|
||||
eap->cmdidx == CMD_def ? &arg_objm : NULL,
|
||||
NULL, &varargs, &default_args, eap->skip,
|
||||
eap, class_flags, &newlines, lines_to_free) == FAIL)
|
||||
goto errret_2;
|
||||
@@ -5252,7 +5297,8 @@ define_function(
|
||||
// The function may use script variables from the context.
|
||||
function_using_block_scopes(fp, cstack);
|
||||
|
||||
if (parse_argument_types(fp, &argtypes, varargs) == FAIL)
|
||||
if (parse_argument_types(fp, &argtypes, varargs, &arg_objm,
|
||||
obj_members, obj_member_count) == FAIL)
|
||||
{
|
||||
SOURCING_LNUM = lnum_save;
|
||||
free_fp = fp_allocated;
|
||||
@@ -5352,6 +5398,7 @@ errret_2:
|
||||
VIM_CLEAR(fp);
|
||||
ret_free:
|
||||
ga_clear_strings(&argtypes);
|
||||
ga_clear(&arg_objm);
|
||||
vim_free(fudi.fd_newkey);
|
||||
if (name != name_arg)
|
||||
vim_free(name);
|
||||
@@ -5370,7 +5417,7 @@ ex_function(exarg_T *eap)
|
||||
garray_T lines_to_free;
|
||||
|
||||
ga_init2(&lines_to_free, sizeof(char_u *), 50);
|
||||
(void)define_function(eap, NULL, &lines_to_free, 0);
|
||||
(void)define_function(eap, NULL, &lines_to_free, 0, NULL, 0);
|
||||
ga_clear_strings(&lines_to_free);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user