mirror of
https://github.com/vim/vim.git
synced 2025-11-16 23:24:03 -05:00
patch 9.1.1577: Vim9: no generic support yet
Problem: Vim9: no generic support yet
Solution: Add support for generic functions, funcrefs and object/class
methods (Yegappan Lakshmanan).
closes: #17313
Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
b486ed8266
commit
3416cee36f
106
src/vim9type.c
106
src/vim9type.c
@@ -101,7 +101,7 @@ copy_type_deep_rec(type_T *type, garray_T *type_gap, garray_T *seen_types)
|
||||
* Make a deep copy of "type".
|
||||
* When allocation fails returns "type".
|
||||
*/
|
||||
static type_T *
|
||||
type_T *
|
||||
copy_type_deep(type_T *type, garray_T *type_gap)
|
||||
{
|
||||
garray_T seen_types;
|
||||
@@ -342,7 +342,10 @@ get_list_type(type_T *member_type, garray_T *type_gap)
|
||||
type_T *type;
|
||||
|
||||
// recognize commonly used types
|
||||
if (member_type == NULL || member_type->tt_type == VAR_ANY)
|
||||
// A generic type is t_any initially before being set to a concrete type
|
||||
// later. So don't use the static t_list_any for a generic type.
|
||||
if (member_type == NULL || (member_type->tt_type == VAR_ANY
|
||||
&& !IS_GENERIC_TYPE(member_type)))
|
||||
return &t_list_any;
|
||||
if (member_type->tt_type == VAR_VOID
|
||||
|| member_type->tt_type == VAR_UNKNOWN)
|
||||
@@ -810,7 +813,29 @@ fp_typval2type(typval_T *tv, garray_T *type_gap)
|
||||
type_gap);
|
||||
}
|
||||
else
|
||||
ufunc = find_func(name, FALSE);
|
||||
{
|
||||
// Check if name contains "<". If it does, then replace "<" with
|
||||
// NUL and lookup the function and then look up the specific
|
||||
// generic function using the supplied types.
|
||||
char_u *p = generic_func_find_open_bracket(name);
|
||||
if (p == NULL)
|
||||
ufunc = find_func(name, FALSE);
|
||||
else
|
||||
{
|
||||
// generic function
|
||||
char_u cc = *p;
|
||||
|
||||
*p = NUL;
|
||||
ufunc = find_func(name, FALSE);
|
||||
*p = cc;
|
||||
if (ufunc != NULL && IS_GENERIC_FUNC(ufunc))
|
||||
{
|
||||
ufunc = find_generic_func(ufunc, name, &p);
|
||||
if (ufunc == NULL)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ufunc != NULL)
|
||||
{
|
||||
@@ -1582,7 +1607,9 @@ parse_type_member(
|
||||
type_T *type,
|
||||
garray_T *type_gap,
|
||||
int give_error,
|
||||
char *info)
|
||||
char *info,
|
||||
ufunc_T *ufunc,
|
||||
cctx_T *cctx)
|
||||
{
|
||||
char_u *arg_start = *arg;
|
||||
type_T *member_type;
|
||||
@@ -1601,7 +1628,7 @@ parse_type_member(
|
||||
}
|
||||
*arg = skipwhite(*arg + 1);
|
||||
|
||||
member_type = parse_type(arg, type_gap, give_error);
|
||||
member_type = parse_type(arg, type_gap, ufunc, cctx, give_error);
|
||||
if (member_type == NULL)
|
||||
return NULL;
|
||||
|
||||
@@ -1625,7 +1652,13 @@ parse_type_member(
|
||||
* Return NULL for failure.
|
||||
*/
|
||||
static type_T *
|
||||
parse_type_func(char_u **arg, size_t len, garray_T *type_gap, int give_error)
|
||||
parse_type_func(
|
||||
char_u **arg,
|
||||
size_t len,
|
||||
garray_T *type_gap,
|
||||
int give_error,
|
||||
ufunc_T *ufunc,
|
||||
cctx_T *cctx)
|
||||
{
|
||||
char_u *p;
|
||||
type_T *type;
|
||||
@@ -1665,7 +1698,7 @@ parse_type_func(char_u **arg, size_t len, garray_T *type_gap, int give_error)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
type = parse_type(&p, type_gap, give_error);
|
||||
type = parse_type(&p, type_gap, ufunc, cctx, give_error);
|
||||
if (type == NULL)
|
||||
return NULL;
|
||||
if ((flags & TTFLAG_VARARGS) != 0 && type->tt_type != VAR_LIST)
|
||||
@@ -1725,7 +1758,7 @@ parse_type_func(char_u **arg, size_t len, garray_T *type_gap, int give_error)
|
||||
if (!VIM_ISWHITE(**arg) && give_error)
|
||||
semsg(_(e_white_space_required_after_str_str), ":", *arg - 1);
|
||||
*arg = skipwhite(*arg);
|
||||
ret_type = parse_type(arg, type_gap, give_error);
|
||||
ret_type = parse_type(arg, type_gap, ufunc, cctx, give_error);
|
||||
if (ret_type == NULL)
|
||||
return NULL;
|
||||
}
|
||||
@@ -1755,7 +1788,12 @@ parse_type_func(char_u **arg, size_t len, garray_T *type_gap, int give_error)
|
||||
* Return NULL for failure.
|
||||
*/
|
||||
static type_T *
|
||||
parse_type_tuple(char_u **arg, garray_T *type_gap, int give_error)
|
||||
parse_type_tuple(
|
||||
char_u **arg,
|
||||
garray_T *type_gap,
|
||||
int give_error,
|
||||
ufunc_T *ufunc,
|
||||
cctx_T *cctx)
|
||||
{
|
||||
char_u *p;
|
||||
type_T *type;
|
||||
@@ -1792,7 +1830,7 @@ parse_type_tuple(char_u **arg, garray_T *type_gap, int give_error)
|
||||
p += 3;
|
||||
}
|
||||
|
||||
type = parse_type(&p, type_gap, give_error);
|
||||
type = parse_type(&p, type_gap, ufunc, cctx, give_error);
|
||||
if (type == NULL)
|
||||
goto on_err;
|
||||
|
||||
@@ -1865,7 +1903,11 @@ on_err:
|
||||
* Return NULL for failure.
|
||||
*/
|
||||
static type_T *
|
||||
parse_type_object(char_u **arg, garray_T *type_gap, int give_error)
|
||||
parse_type_object(
|
||||
char_u **arg,
|
||||
garray_T *type_gap,
|
||||
int give_error,
|
||||
cctx_T *cctx)
|
||||
{
|
||||
char_u *arg_start = *arg;
|
||||
type_T *object_type;
|
||||
@@ -1889,7 +1931,7 @@ parse_type_object(char_u **arg, garray_T *type_gap, int give_error)
|
||||
// skip spaces following "object<"
|
||||
*arg = skipwhite(*arg + 1);
|
||||
|
||||
object_type = parse_type(arg, type_gap, give_error);
|
||||
object_type = parse_type(arg, type_gap, NULL, cctx, give_error);
|
||||
if (object_type == NULL)
|
||||
return NULL;
|
||||
|
||||
@@ -1926,7 +1968,9 @@ parse_type_user_defined(
|
||||
char_u **arg,
|
||||
size_t len,
|
||||
garray_T *type_gap,
|
||||
int give_error)
|
||||
int give_error,
|
||||
ufunc_T *ufunc,
|
||||
cctx_T *cctx)
|
||||
{
|
||||
int did_emsg_before = did_emsg;
|
||||
typval_T tv;
|
||||
@@ -1968,6 +2012,14 @@ parse_type_user_defined(
|
||||
clear_tv(&tv);
|
||||
}
|
||||
|
||||
// Check whether it is a generic type
|
||||
type_T *type = find_generic_type(*arg, len, ufunc, cctx);
|
||||
if (type != NULL)
|
||||
{
|
||||
*arg += len;
|
||||
return type;
|
||||
}
|
||||
|
||||
if (give_error && (did_emsg == did_emsg_before))
|
||||
{
|
||||
char_u *p = skip_type(*arg, FALSE);
|
||||
@@ -1987,7 +2039,12 @@ parse_type_user_defined(
|
||||
* Return NULL for failure.
|
||||
*/
|
||||
type_T *
|
||||
parse_type(char_u **arg, garray_T *type_gap, int give_error)
|
||||
parse_type(
|
||||
char_u **arg,
|
||||
garray_T *type_gap,
|
||||
ufunc_T *ufunc,
|
||||
cctx_T *cctx,
|
||||
int give_error)
|
||||
{
|
||||
char_u *p = *arg;
|
||||
size_t len;
|
||||
@@ -2029,8 +2086,9 @@ parse_type(char_u **arg, garray_T *type_gap, int give_error)
|
||||
if (len == 4 && STRNCMP(*arg, "dict", len) == 0)
|
||||
{
|
||||
*arg += len;
|
||||
return parse_type_member(arg, &t_dict_any,
|
||||
type_gap, give_error, "dict");
|
||||
return parse_type_member(arg, &t_dict_any, type_gap,
|
||||
give_error, "dict", ufunc,
|
||||
cctx);
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
@@ -2040,7 +2098,8 @@ parse_type(char_u **arg, garray_T *type_gap, int give_error)
|
||||
return &t_float;
|
||||
}
|
||||
if (len == 4 && STRNCMP(*arg, "func", len) == 0)
|
||||
return parse_type_func(arg, len, type_gap, give_error);
|
||||
return parse_type_func(arg, len, type_gap, give_error, ufunc,
|
||||
cctx);
|
||||
break;
|
||||
case 'j':
|
||||
if (len == 3 && STRNCMP(*arg, "job", len) == 0)
|
||||
@@ -2053,8 +2112,9 @@ parse_type(char_u **arg, garray_T *type_gap, int give_error)
|
||||
if (len == 4 && STRNCMP(*arg, "list", len) == 0)
|
||||
{
|
||||
*arg += len;
|
||||
return parse_type_member(arg, &t_list_any,
|
||||
type_gap, give_error, "list");
|
||||
return parse_type_member(arg, &t_list_any, type_gap,
|
||||
give_error, "list", ufunc,
|
||||
cctx);
|
||||
}
|
||||
break;
|
||||
case 'n':
|
||||
@@ -2068,7 +2128,7 @@ parse_type(char_u **arg, garray_T *type_gap, int give_error)
|
||||
if (len == 6 && STRNCMP(*arg, "object", len) == 0)
|
||||
{
|
||||
*arg += len;
|
||||
return parse_type_object(arg, type_gap, give_error);
|
||||
return parse_type_object(arg, type_gap, give_error, cctx);
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
@@ -2082,7 +2142,8 @@ parse_type(char_u **arg, garray_T *type_gap, int give_error)
|
||||
if (len == 5 && STRNCMP(*arg, "tuple", len) == 0)
|
||||
{
|
||||
*arg += len;
|
||||
return parse_type_tuple(arg, type_gap, give_error);
|
||||
return parse_type_tuple(arg, type_gap, give_error, ufunc,
|
||||
cctx);
|
||||
}
|
||||
break;
|
||||
case 'v':
|
||||
@@ -2095,7 +2156,8 @@ parse_type(char_u **arg, garray_T *type_gap, int give_error)
|
||||
}
|
||||
|
||||
// User defined type
|
||||
return parse_type_user_defined(arg, len, type_gap, give_error);
|
||||
return parse_type_user_defined(arg, len, type_gap, give_error, ufunc,
|
||||
cctx);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user