1
0
forked from aniani/vim

patch 9.0.1147: cannot access a class member in a compiled function

Problem:    Cannot access a class member in a compiled function.
Solution:   Implement looking up a class member.
This commit is contained in:
Bram Moolenaar
2023-01-04 18:54:09 +00:00
parent c8b204952f
commit 3259ff3b3b
3 changed files with 38 additions and 18 deletions

View File

@@ -439,6 +439,11 @@ def Test_class_member()
TextPos.AddToCounter(3) TextPos.AddToCounter(3)
assert_equal(3, TextPos.counter) assert_equal(3, TextPos.counter)
assert_fails('echo TextPos.noSuchMember', 'E1338:') assert_fails('echo TextPos.noSuchMember', 'E1338:')
def GetCounter(): number
return TextPos.counter
enddef
assert_equal(3, GetCounter())
assert_fails('TextPos.noSuchMember = 2', 'E1337:') assert_fails('TextPos.noSuchMember = 2', 'E1337:')
assert_fails('TextPos.counter = 5', 'E1335:') assert_fails('TextPos.counter = 5', 'E1335:')

View File

@@ -695,6 +695,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1147,
/**/ /**/
1146, 1146,
/**/ /**/

View File

@@ -263,6 +263,22 @@ compile_class_object_index(cctx_T *cctx, char_u **arg, type_T *type)
return FAIL; return FAIL;
} }
if (type->tt_type == VAR_CLASS)
{
garray_T *instr = &cctx->ctx_instr;
if (instr->ga_len > 0)
{
isn_T *isn = ((isn_T *)instr->ga_data) + instr->ga_len - 1;
if (isn->isn_type == ISN_LOADSCRIPT)
{
// The class was recognized as a script item. We only need
// to know what class it is, drop the instruction.
--instr->ga_len;
vim_free(isn->isn_arg.script.scriptref);
}
}
}
++*arg; ++*arg;
char_u *name = *arg; char_u *name = *arg;
char_u *name_end = find_name_end(name, NULL, NULL, FNE_CHECK_START); char_u *name_end = find_name_end(name, NULL, NULL, FNE_CHECK_START);
@@ -278,19 +294,6 @@ compile_class_object_index(cctx_T *cctx, char_u **arg, type_T *type)
if (type->tt_type == VAR_CLASS) if (type->tt_type == VAR_CLASS)
{ {
garray_T *instr = &cctx->ctx_instr;
if (instr->ga_len > 0)
{
isn_T *isn = ((isn_T *)instr->ga_data) + instr->ga_len - 1;
if (isn->isn_type == ISN_LOADSCRIPT)
{
// The class was recognized as a script item. We only need
// to know what class it is, drop the instruction.
--instr->ga_len;
vim_free(isn->isn_arg.script.scriptref);
}
}
function_count = cl->class_class_function_count; function_count = cl->class_class_function_count;
functions = cl->class_class_functions; functions = cl->class_class_functions;
} }
@@ -344,10 +347,8 @@ compile_class_object_index(cctx_T *cctx, char_u **arg, type_T *type)
return FAIL; return FAIL;
} }
generate_GET_OBJ_MEMBER(cctx, i, m->ocm_type);
*arg = name_end; *arg = name_end;
return OK; return generate_GET_OBJ_MEMBER(cctx, i, m->ocm_type);
} }
} }
@@ -355,8 +356,20 @@ compile_class_object_index(cctx_T *cctx, char_u **arg, type_T *type)
} }
else else
{ {
// TODO: class member // load class member
emsg("compile_class_object_index(): class member not handled yet"); int idx;
for (idx = 0; idx < cl->class_class_member_count; ++idx)
{
ocmember_T *m = &cl->class_class_members[idx];
if (STRNCMP(name, m->ocm_name, len) == 0 && m->ocm_name[len] == NUL)
break;
}
if (idx < cl->class_class_member_count)
{
*arg = name_end;
return generate_CLASSMEMBER(cctx, TRUE, cl, idx);
}
semsg(_(e_class_member_not_found_str), name);
} }
return FAIL; return FAIL;