garray_T *newargs,
garray_T *argtypes,
int types_optional,
+ garray_T *arg_objm,
evalarg_T *evalarg,
exarg_T *eap,
int is_vararg,
}
// 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;
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;
}
}
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,
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);
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) == '=')
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)
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;
* 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;
// 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;
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;
garray_T *pnewargs;
garray_T argtypes;
garray_T default_args;
+ garray_T arg_objm;
ufunc_T *fp = NULL;
partial_T *pt = NULL;
int varargs;
// 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;
}
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
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;
}
if (types_optional)
{
if (parse_argument_types(fp, &argtypes,
- vim9script && varargs) == FAIL)
+ vim9script && varargs, NULL, NULL, 0) == FAIL)
goto errret;
if (ret_type != NULL)
{
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;
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;
ga_init(&newargs);
ga_init(&argtypes);
+ ga_init(&arg_objm);
ga_init(&default_args);
/*
++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;
// 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;
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);
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);
}
if (type->tt_type == VAR_OBJECT
&& (cl->class_flags & (CLASS_INTERFACE | CLASS_EXTENDED)))
- return generate_CALL(cctx, ufunc, cl, fi, type, argcount);
- return generate_CALL(cctx, ufunc, NULL, 0, type, argcount);
+ return generate_CALL(cctx, ufunc, cl, fi, argcount);
+ return generate_CALL(cctx, ufunc, NULL, 0, argcount);
}
if (type->tt_type == VAR_OBJECT)
int has_g_namespace;
ca_special_T special_fn;
imported_T *import;
- type_T *type;
if (varlen >= sizeof(namebuf))
{
if (compile_arguments(arg, cctx, &argcount, special_fn) == FAIL)
goto theend;
- type = get_decl_type_on_stack(cctx, 1);
is_autoload = vim_strchr(name, AUTOLOAD_CHAR) != NULL;
if (ASCII_ISLOWER(*name) && name[1] != ':' && !is_autoload)
{
if (STRCMP(name, "add") == 0 && argcount == 2)
{
+ type_T *type = get_decl_type_on_stack(cctx, 1);
+
// add() can be compiled to instructions if we know the type
if (type->tt_type == VAR_LIST)
{
{
if (!func_is_global(ufunc))
{
- res = generate_CALL(cctx, ufunc, NULL, 0, type, argcount);
+ res = generate_CALL(cctx, ufunc, NULL, 0, argcount);
goto theend;
}
if (!has_g_namespace
if (cctx->ctx_ufunc->uf_defclass == cl)
{
res = generate_CALL(cctx, cl->class_class_functions[mi], NULL,
- 0, type, argcount);
+ 0, argcount);
}
else
{
// If we can find a global function by name generate the right call.
if (ufunc != NULL)
{
- res = generate_CALL(cctx, ufunc, NULL, 0, type, argcount);
+ res = generate_CALL(cctx, ufunc, NULL, 0, argcount);
goto theend;
}