0
0
mirror of https://github.com/vim/vim.git synced 2025-09-23 03:43:49 -04:00

patch 9.0.1074: class members are not supported yet

Problem:    Class members are not supported yet.
Solution:   Add initial support for class members.
This commit is contained in:
Bram Moolenaar
2022-12-18 21:42:55 +00:00
parent 731d00770d
commit d505d17885
13 changed files with 578 additions and 215 deletions

View File

@@ -301,6 +301,28 @@ script_var_exists(char_u *name, size_t len, cctx_T *cctx, cstack_T *cstack)
return FAIL;
}
/*
* If "name" is a class member in cctx->ctx_ufunc->uf_class return the index in
* class.class_class_members[].
* Otherwise return -1;
*/
static int
class_member_index(char_u *name, size_t len, cctx_T *cctx)
{
if (cctx == NULL || cctx->ctx_ufunc == NULL
|| cctx->ctx_ufunc->uf_class == NULL)
return -1;
class_T *cl = cctx->ctx_ufunc->uf_class;
for (int i = 0; i < cl->class_class_member_count; ++i)
{
ocmember_T *m = &cl->class_class_members[i];
if (STRNCMP(name, m->ocm_name, len) == 0
&& m->ocm_name[len] == NUL)
return i;
}
return -1;
}
/*
* Return TRUE if "name" is a local variable, argument, script variable or
* imported.
@@ -316,6 +338,7 @@ variable_exists(char_u *name, size_t len, cctx_T *cctx)
&& (cctx->ctx_ufunc->uf_flags & FC_OBJECT)
&& STRNCMP(name, "this", 4) == 0)))
|| script_var_exists(name, len, cctx, NULL) == OK
|| class_member_index(name, len, cctx) >= 0
|| find_imported(name, len, FALSE) != NULL;
}
@@ -353,6 +376,9 @@ check_defined(
if (len == 1 && *p == '_')
return OK;
if (class_member_index(p, len, cctx) >= 0)
return OK;
if (script_var_exists(p, len, cctx, cstack) == OK)
{
if (is_arg)
@@ -1195,14 +1221,12 @@ assignment_len(char_u *p, int *heredoc)
* Generate the load instruction for "name".
*/
static void
generate_loadvar(
cctx_T *cctx,
assign_dest_T dest,
char_u *name,
lvar_T *lvar,
type_T *type)
generate_loadvar(cctx_T *cctx, lhs_T *lhs)
{
switch (dest)
char_u *name = lhs->lhs_name;
type_T *type = lhs->lhs_type;
switch (lhs->lhs_dest)
{
case dest_option:
case dest_func_option:
@@ -1245,6 +1269,7 @@ generate_loadvar(
case dest_local:
if (cctx->ctx_skip != SKIP_YES)
{
lvar_T *lvar = lhs->lhs_lvar;
if (lvar->lv_from_outer > 0)
generate_LOADOUTER(cctx, lvar->lv_idx, lvar->lv_from_outer,
lvar->lv_loop_depth, lvar->lv_loop_idx, type);
@@ -1252,6 +1277,10 @@ generate_loadvar(
generate_LOAD(cctx, ISN_LOAD, lvar->lv_idx, NULL, type);
}
break;
case dest_class_member:
generate_CLASSMEMBER(cctx, TRUE, lhs->lhs_class,
lhs->lhs_classmember_idx);
break;
case dest_expr:
// list or dict value should already be on the stack.
break;
@@ -1533,7 +1562,9 @@ compile_lhs(
if (lookup_local(var_start, lhs->lhs_varlen,
&lhs->lhs_local_lvar, cctx) == OK)
{
lhs->lhs_lvar = &lhs->lhs_local_lvar;
}
else
{
CLEAR_FIELD(lhs->lhs_arg_lvar);
@@ -1549,6 +1580,7 @@ compile_lhs(
lhs->lhs_lvar = &lhs->lhs_arg_lvar;
}
}
if (lhs->lhs_lvar != NULL)
{
if (is_decl)
@@ -1557,6 +1589,12 @@ compile_lhs(
return FAIL;
}
}
else if ((lhs->lhs_classmember_idx = class_member_index(
var_start, lhs->lhs_varlen, cctx)) >= 0)
{
lhs->lhs_dest = dest_class_member;
lhs->lhs_class = cctx->ctx_ufunc->uf_class;
}
else
{
int script_namespace = lhs->lhs_varlen > 1
@@ -1965,8 +2003,7 @@ compile_load_lhs(
return FAIL;
}
else
generate_loadvar(cctx, lhs->lhs_dest, lhs->lhs_name,
lhs->lhs_lvar, lhs->lhs_type);
generate_loadvar(cctx, lhs);
return OK;
}
@@ -2998,20 +3035,20 @@ compile_def_function(
for (int i = 0; i < ufunc->uf_class->class_obj_member_count; ++i)
{
objmember_T *m = &ufunc->uf_class->class_obj_members[i];
if (m->om_init != NULL)
ocmember_T *m = &ufunc->uf_class->class_obj_members[i];
if (m->ocm_init != NULL)
{
char_u *expr = m->om_init;
char_u *expr = m->ocm_init;
if (compile_expr0(&expr, &cctx) == FAIL)
goto erret;
if (!ends_excmd2(m->om_init, expr))
if (!ends_excmd2(m->ocm_init, expr))
{
semsg(_(e_trailing_characters_str), expr);
goto erret;
}
}
else
push_default_value(&cctx, m->om_type->tt_type,
push_default_value(&cctx, m->ocm_type->tt_type,
FALSE, NULL);
generate_STORE_THIS(&cctx, i);
}
@@ -3792,6 +3829,13 @@ delete_def_function_contents(dfunc_T *dfunc, int mark_deleted)
{
int idx;
// In same cases the instructions may refer to a class in which the
// function is defined and unreferencing the class may call back here
// recursively. Set the df_delete_busy to avoid problems.
if (dfunc->df_delete_busy)
return;
dfunc->df_delete_busy = TRUE;
ga_clear(&dfunc->df_def_args_isn);
ga_clear_strings(&dfunc->df_var_names);
@@ -3800,14 +3844,12 @@ delete_def_function_contents(dfunc_T *dfunc, int mark_deleted)
for (idx = 0; idx < dfunc->df_instr_count; ++idx)
delete_instr(dfunc->df_instr + idx);
VIM_CLEAR(dfunc->df_instr);
dfunc->df_instr = NULL;
}
if (dfunc->df_instr_debug != NULL)
{
for (idx = 0; idx < dfunc->df_instr_debug_count; ++idx)
delete_instr(dfunc->df_instr_debug + idx);
VIM_CLEAR(dfunc->df_instr_debug);
dfunc->df_instr_debug = NULL;
}
#ifdef FEAT_PROFILE
if (dfunc->df_instr_prof != NULL)
@@ -3815,7 +3857,6 @@ delete_def_function_contents(dfunc_T *dfunc, int mark_deleted)
for (idx = 0; idx < dfunc->df_instr_prof_count; ++idx)
delete_instr(dfunc->df_instr_prof + idx);
VIM_CLEAR(dfunc->df_instr_prof);
dfunc->df_instr_prof = NULL;
}
#endif
@@ -3823,6 +3864,8 @@ delete_def_function_contents(dfunc_T *dfunc, int mark_deleted)
dfunc->df_deleted = TRUE;
if (dfunc->df_ufunc != NULL)
dfunc->df_ufunc->uf_def_status = UF_NOT_COMPILED;
dfunc->df_delete_busy = FALSE;
}
/*