mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
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)
This commit is contained in:
parent
b149d22796
commit
62a6923470
@ -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);
|
int class_object_index(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int verbose);
|
||||||
ufunc_T *find_class_func(char_u **arg);
|
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 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 copy_object(typval_T *from, typval_T *to);
|
||||||
void object_unref(object_T *obj);
|
void object_unref(object_T *obj);
|
||||||
void copy_class(typval_T *from, typval_T *to);
|
void copy_class(typval_T *from, typval_T *to);
|
||||||
|
@ -645,6 +645,24 @@ def Test_class_member()
|
|||||||
END
|
END
|
||||||
v9.CheckScriptSuccess(lines)
|
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
|
# check shadowing
|
||||||
lines =<< trim END
|
lines =<< trim END
|
||||||
vim9script
|
vim9script
|
||||||
|
@ -695,6 +695,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1240,
|
||||||
/**/
|
/**/
|
||||||
1239,
|
1239,
|
||||||
/**/
|
/**/
|
||||||
|
@ -1387,6 +1387,19 @@ class_member_index(char_u *name, size_t len, class_T **cl_ret, cctx_T *cctx)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
* Make a copy of an object.
|
||||||
*/
|
*/
|
||||||
|
@ -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];
|
ocmember_T *m = &cl->class_obj_members[i];
|
||||||
if (STRNCMP(name, m->ocm_name, len) == 0 && m->ocm_name[len] == NUL)
|
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);
|
semsg(_(e_cannot_access_private_member_str), m->ocm_name);
|
||||||
return FAIL;
|
return FAIL;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user