Mercurial > vim
changeset 31815:64f03e860c91 v9.0.1240
patch 9.0.1240: cannot access a private object member in a lambda
Commit: https://github.com/vim/vim/commit/62a6923470827acbf124df41134ae6df52f334e6
Author: Bram Moolenaar <Bram@vim.org>
Date: Tue Jan 24 15:07:04 2023 +0000
patch 9.0.1240: cannot access a private object member in a lambda
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)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Tue, 24 Jan 2023 16:15:07 +0100 |
parents | 19d470f5723f |
children | 312ba23c4830 |
files | src/proto/vim9class.pro src/testdir/test_vim9_class.vim src/version.c src/vim9class.c src/vim9expr.c |
diffstat | 5 files changed, 35 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- 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);
--- 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
--- 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,
--- a/src/vim9class.c +++ b/src/vim9class.c @@ -1388,6 +1388,19 @@ class_member_index(char_u *name, size_t } /* + * 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
--- a/src/vim9expr.c +++ b/src/vim9expr.c @@ -357,7 +357,7 @@ compile_class_object_index(cctx_T *cctx, 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;