mirror of
https://github.com/vim/vim.git
synced 2025-09-24 03:44:06 -04:00
patch 9.0.2170: Vim9: no support for const/final class/objects vars
Problem: Vim9: no support for const/final class/objects vars Solution: Support final and const object and class variables closes: #13655 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
d8bf87c9fb
commit
e5437c5427
114
src/vim9class.c
114
src/vim9class.c
@@ -152,6 +152,19 @@ parse_member(
|
||||
return OK;
|
||||
}
|
||||
|
||||
typedef struct oc_newmember_S oc_newmember_T;
|
||||
struct oc_newmember_S
|
||||
{
|
||||
garray_T *gap;
|
||||
char_u *varname;
|
||||
char_u *varname_end;
|
||||
int has_public;
|
||||
int has_final;
|
||||
int has_type;
|
||||
type_T *type;
|
||||
char_u *init_expr;
|
||||
};
|
||||
|
||||
/*
|
||||
* Add a member to an object or a class.
|
||||
* Returns OK when successful, "init_expr" will be consumed then.
|
||||
@@ -163,6 +176,8 @@ add_member(
|
||||
char_u *varname,
|
||||
char_u *varname_end,
|
||||
int has_public,
|
||||
int has_final,
|
||||
int has_const,
|
||||
int has_type,
|
||||
type_T *type,
|
||||
char_u *init_expr)
|
||||
@@ -173,7 +188,12 @@ add_member(
|
||||
m->ocm_name = vim_strnsave(varname, varname_end - varname);
|
||||
m->ocm_access = has_public ? VIM_ACCESS_ALL
|
||||
: *varname == '_' ? VIM_ACCESS_PRIVATE : VIM_ACCESS_READ;
|
||||
m->ocm_has_type = has_type;
|
||||
if (has_final)
|
||||
m->ocm_flags |= OCMFLAG_FINAL;
|
||||
if (has_const)
|
||||
m->ocm_flags |= OCMFLAG_CONST;
|
||||
if (has_type)
|
||||
m->ocm_flags |= OCMFLAG_HAS_TYPE;
|
||||
m->ocm_type = type;
|
||||
if (init_expr != NULL)
|
||||
m->ocm_init = init_expr;
|
||||
@@ -1132,7 +1152,7 @@ add_class_members(class_T *cl, exarg_T *eap, garray_T *type_list_gap)
|
||||
if (etv != NULL)
|
||||
{
|
||||
if (m->ocm_type->tt_type == VAR_ANY
|
||||
&& !m->ocm_has_type
|
||||
&& !(m->ocm_flags & OCMFLAG_HAS_TYPE)
|
||||
&& etv->v_type != VAR_SPECIAL)
|
||||
// If the member variable type is not yet set, then use
|
||||
// the initialization expression type.
|
||||
@@ -1149,6 +1169,8 @@ add_class_members(class_T *cl, exarg_T *eap, garray_T *type_list_gap)
|
||||
tv->v_type = m->ocm_type->tt_type;
|
||||
tv->vval.v_string = NULL;
|
||||
}
|
||||
if (m->ocm_flags & OCMFLAG_CONST)
|
||||
item_lock(tv, DICT_MAXNEST, TRUE, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1558,9 +1580,10 @@ early_ret:
|
||||
has_public = TRUE;
|
||||
p = skipwhite(line + 6);
|
||||
|
||||
if (STRNCMP(p, "var", 3) != 0 && STRNCMP(p, "static", 6) != 0)
|
||||
if (STRNCMP(p, "var", 3) != 0 && STRNCMP(p, "static", 6) != 0
|
||||
&& STRNCMP(p, "final", 5) != 0 && STRNCMP(p, "const", 5) != 0)
|
||||
{
|
||||
emsg(_(e_public_must_be_followed_by_var_or_static));
|
||||
emsg(_(e_public_must_be_followed_by_var_static_final_or_const));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1616,22 +1639,60 @@ early_ret:
|
||||
has_static = TRUE;
|
||||
p = skipwhite(ps + 6);
|
||||
|
||||
if (STRNCMP(p, "var", 3) != 0 && STRNCMP(p, "def", 3) != 0)
|
||||
if (STRNCMP(p, "var", 3) != 0 && STRNCMP(p, "def", 3) != 0
|
||||
&& STRNCMP(p, "final", 5) != 0 && STRNCMP(p, "const", 5) != 0)
|
||||
{
|
||||
emsg(_(e_static_must_be_followed_by_var_or_def));
|
||||
emsg(_(e_static_must_be_followed_by_var_def_final_or_const));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int has_final = FALSE;
|
||||
int has_var = FALSE;
|
||||
int has_const = FALSE;
|
||||
if (checkforcmd(&p, "var", 3))
|
||||
has_var = TRUE;
|
||||
else if (checkforcmd(&p, "final", 5))
|
||||
{
|
||||
if (!is_class)
|
||||
{
|
||||
emsg(_(e_final_variable_not_supported_in_interface));
|
||||
break;
|
||||
}
|
||||
has_final = TRUE;
|
||||
}
|
||||
else if (checkforcmd(&p, "const", 5))
|
||||
{
|
||||
if (!is_class)
|
||||
{
|
||||
emsg(_(e_const_variable_not_supported_in_interface));
|
||||
break;
|
||||
}
|
||||
has_const = TRUE;
|
||||
}
|
||||
p = skipwhite(p);
|
||||
|
||||
// object members (public, read access, private):
|
||||
// "var _varname"
|
||||
// "var varname"
|
||||
// "public var varname"
|
||||
// "final _varname"
|
||||
// "final varname"
|
||||
// "public final varname"
|
||||
// "const _varname"
|
||||
// "const varname"
|
||||
// "public const varname"
|
||||
// class members (public, read access, private):
|
||||
// "static var _varname"
|
||||
// "static var varname"
|
||||
// "public static var varname"
|
||||
if (checkforcmd(&p, "var", 3))
|
||||
// "static final _varname"
|
||||
// "static final varname"
|
||||
// "public static final varname"
|
||||
// "static const _varname"
|
||||
// "static const varname"
|
||||
// "public static const varname"
|
||||
if (has_var || has_final || has_const)
|
||||
{
|
||||
char_u *varname = p;
|
||||
char_u *varname_end = NULL;
|
||||
@@ -1671,8 +1732,9 @@ early_ret:
|
||||
vim_free(init_expr);
|
||||
break;
|
||||
}
|
||||
if (add_member(has_static ? &classmembers : &objmembers, varname, varname_end,
|
||||
has_public, has_type, type, init_expr) == FAIL)
|
||||
if (add_member(has_static ? &classmembers : &objmembers, varname,
|
||||
varname_end, has_public, has_final, has_const,
|
||||
has_type, type, init_expr) == FAIL)
|
||||
{
|
||||
vim_free(init_expr);
|
||||
break;
|
||||
@@ -2779,6 +2841,40 @@ inside_class(cctx_T *cctx_arg, class_T *cl)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return TRUE if object/class variable "m" is read-only.
|
||||
* Also give an error message.
|
||||
*/
|
||||
int
|
||||
oc_var_check_ro(class_T *cl, ocmember_T *m)
|
||||
{
|
||||
if (m->ocm_flags & (OCMFLAG_FINAL | OCMFLAG_CONST))
|
||||
{
|
||||
semsg(_(e_cannot_change_readonly_variable_str_in_class_str),
|
||||
m->ocm_name, cl->class_name);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Lock all the constant object variables. Called after creating and
|
||||
* initializing a new object.
|
||||
*/
|
||||
void
|
||||
obj_lock_const_vars(object_T *obj)
|
||||
{
|
||||
for (int i = 0; i < obj->obj_class->class_obj_member_count; i++)
|
||||
{
|
||||
ocmember_T *ocm = &obj->obj_class->class_obj_members[i];
|
||||
if (ocm->ocm_flags & OCMFLAG_CONST)
|
||||
{
|
||||
typval_T *mtv = ((typval_T *)(obj + 1)) + i;
|
||||
item_lock(mtv, DICT_MAXNEST, TRUE, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Make a copy of an object.
|
||||
*/
|
||||
|
Reference in New Issue
Block a user