summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/proto/vim9class.pro1
-rw-r--r--src/testdir/test_vim9_class.vim18
-rw-r--r--src/version.c2
-rw-r--r--src/vim9class.c13
-rw-r--r--src/vim9expr.c2
5 files changed, 35 insertions, 1 deletions
diff --git a/src/proto/vim9class.pro b/src/proto/vim9class.pro
index 74d33c00c..13a643dd5 100644
--- a/src/proto/vim9class.pro
+++ b/src/proto/vim9class.pro
@@ -7,6 +7,7 @@ void ex_type(exarg_T *eap);
int class_object_index(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int verbose);
ufunc_T *find_class_func(char_u **arg);
int class_member_index(char_u *name, size_t len, class_T **cl_ret, cctx_T *cctx);
+int inside_class(cctx_T *cctx_arg, class_T *cl);
void copy_object(typval_T *from, typval_T *to);
void object_unref(object_T *obj);
void copy_class(typval_T *from, typval_T *to);
diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim
index a3fdbdb9c..389213680 100644
--- a/src/testdir/test_vim9_class.vim
+++ b/src/testdir/test_vim9_class.vim
@@ -645,6 +645,24 @@ def Test_class_member()
END
v9.CheckScriptSuccess(lines)
+ # access private member in lambda
+ lines =<< trim END
+ vim9script
+
+ class Foo
+ this._x: number = 0
+
+ def Add(n: number): number
+ const F = (): number => this._x + n
+ return F()
+ enddef
+ endclass
+
+ var foo = Foo.new()
+ assert_equal(5, foo.Add(5))
+ END
+ v9.CheckScriptSuccess(lines)
+
# check shadowing
lines =<< trim END
vim9script
diff --git a/src/version.c b/src/version.c
index f21a1887a..4a3355c0b 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 */
/**/
+ 1240,
+/**/
1239,
/**/
1238,
diff --git a/src/vim9class.c b/src/vim9class.c
index 0262e025d..484500576 100644
--- a/src/vim9class.c
+++ b/src/vim9class.c
@@ -1388,6 +1388,19 @@ class_member_index(char_u *name, size_t len, class_T **cl_ret, cctx_T *cctx)
}
/*
+ * Return TRUE if current context "cctx_arg" is inside class "cl".
+ * Return FALSE if not.
+ */
+ int
+inside_class(cctx_T *cctx_arg, class_T *cl)
+{
+ for (cctx_T *cctx = cctx_arg; cctx != NULL; cctx = cctx->ctx_outer)
+ if (cctx->ctx_ufunc != NULL && cctx->ctx_ufunc->uf_class == cl)
+ return TRUE;
+ return FALSE;
+}
+
+/*
* Make a copy of an object.
*/
void
diff --git a/src/vim9expr.c b/src/vim9expr.c
index 95c6d7db0..1034f64b0 100644
--- a/src/vim9expr.c
+++ b/src/vim9expr.c
@@ -357,7 +357,7 @@ compile_class_object_index(cctx_T *cctx, char_u **arg, type_T *type)
ocmember_T *m = &cl->class_obj_members[i];
if (STRNCMP(name, m->ocm_name, len) == 0 && m->ocm_name[len] == NUL)
{
- if (*name == '_' && cctx->ctx_ufunc->uf_class != cl)
+ if (*name == '_' && !inside_class(cctx, cl))
{
semsg(_(e_cannot_access_private_member_str), m->ocm_name);
return FAIL;