changeset 31630:5400eba7c3f3 v9.0.1147

patch 9.0.1147: cannot access a class member in a compiled function Commit: https://github.com/vim/vim/commit/3259ff3b3bd152d61c1cef7901023034c0d655a3 Author: Bram Moolenaar <Bram@vim.org> Date: Wed Jan 4 18:54:09 2023 +0000 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.
author Bram Moolenaar <Bram@vim.org>
date Wed, 04 Jan 2023 20:00:04 +0100
parents 41f9c768374e
children 5eca287cd239
files src/testdir/test_vim9_class.vim src/version.c src/vim9expr.c
diffstat 3 files changed, 38 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- 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:')
--- 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,
--- a/src/vim9expr.c
+++ b/src/vim9expr.c
@@ -263,6 +263,22 @@ compile_class_object_index(cctx_T *cctx,
 	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,
 
 	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,
 		    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,
     }
     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;