To: vim_dev@googlegroups.com Subject: Patch 9.0.1240 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ 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 -- Bram@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 ///