summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2023-01-04 18:54:09 +0000
committerBram Moolenaar <Bram@vim.org>2023-01-04 18:54:09 +0000
commit3259ff3b3bd152d61c1cef7901023034c0d655a3 (patch)
treefd0aa894a0ba56586ee392eb69ee98e4b3a3d954
parentc8b204952f0452fe1276d30ae6a5d38a3f421b95 (diff)
patch 9.0.1147: cannot access a class member in a compiled functionv9.0.1147
Problem: Cannot access a class member in a compiled function. Solution: Implement looking up a class member.
-rw-r--r--src/testdir/test_vim9_class.vim5
-rw-r--r--src/version.c2
-rw-r--r--src/vim9expr.c49
3 files changed, 38 insertions, 18 deletions
diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim
index 60730c4d5d..a55671bcb6 100644
--- a/src/testdir/test_vim9_class.vim
+++ b/src/testdir/test_vim9_class.vim
@@ -439,6 +439,11 @@ def Test_class_member()
TextPos.AddToCounter(3)
assert_equal(3, TextPos.counter)
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.counter = 5', 'E1335:')
diff --git a/src/version.c b/src/version.c
index 44d8db9b00..39f7a0b0c7 100644
--- a/src/version.c
+++ b/src/version.c
@@ -696,6 +696,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1147,
+/**/
1146,
/**/
1145,
diff --git a/src/vim9expr.c b/src/vim9expr.c
index daf014f84b..3acb97bef6 100644
--- a/src/vim9expr.c
+++ b/src/vim9expr.c
@@ -263,6 +263,22 @@ compile_class_object_index(cctx_T *cctx, char_u **arg, type_T *type)
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;
char_u *name = *arg;
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)
{
- 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;
functions = cl->class_class_functions;
}
@@ -344,10 +347,8 @@ compile_class_object_index(cctx_T *cctx, char_u **arg, type_T *type)
return FAIL;
}
- generate_GET_OBJ_MEMBER(cctx, i, m->ocm_type);
-
*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
{
- // TODO: class member
- emsg("compile_class_object_index(): class member not handled yet");
+ // load class member
+ 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;