Patch 9.0.1240
Problem: Cannot access a private object member in a lambda defined inside
the class.
Solution: Go up the context stack to find the class. (closes #11866)
Files: src/vim9expr.c, src/vim9class.c, src/proto/
vim9class.pro,
src/testdir/test_vim9_class.vim
*** ../vim-9.0.1239/src/vim9expr.c 2023-01-16 19:43:43.390873675 +0000
--- src/vim9expr.c 2023-01-24 15:02:12.412606484 +0000
***************
*** 357,363 ****
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)
{
semsg(_(e_cannot_access_private_member_str), m->ocm_name);
return FAIL;
--- 357,363 ----
ocmember_T *m = &cl->class_obj_members[i];
if (STRNCMP(name, m->ocm_name, len) == 0 && m->ocm_name[len] == NUL)
{
! if (*name == '_' && !inside_class(cctx, cl))
{
semsg(_(e_cannot_access_private_member_str), m->ocm_name);
return FAIL;
*** ../vim-9.0.1239/src/vim9class.c 2023-01-16 19:43:43.390873675 +0000
--- src/vim9class.c 2023-01-24 15:00:33.628647063 +0000
***************
*** 1388,1393 ****
--- 1388,1406 ----
}
/*
+ * 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
*** ../vim-9.0.1239/src/proto/
vim9class.pro 2023-01-16 19:43:43.390873675 +0000
--- src/proto/
vim9class.pro 2023-01-24 15:01:55.460613453 +0000
***************
*** 7,12 ****
--- 7,13 ----
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);
*** ../vim-9.0.1239/src/testdir/test_vim9_class.vim 2023-01-24 13:03:33.223114758 +0000
--- src/testdir/test_vim9_class.vim 2023-01-24 15:04:51.556541181 +0000
***************
*** 645,650 ****
--- 645,668 ----
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
*** ../vim-9.0.1239/src/version.c 2023-01-24 13:03:33.223114758 +0000
--- src/version.c 2023-01-24 15:01:47.476616732 +0000
***************
*** 697,698 ****
--- 697,700 ----
{ /* Add new patch number below this line */
+ /**/
+ 1240,
/**/
--
Well, you come from nothing, you go back to nothing... What have you
lost? Nothing!
-- Monty Python: The life of Brian
/// Bram Moolenaar -- Br...@Moolenaar.net --
http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features --
http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims --
http://ICCF-Holland.org ///