patch 9.1.2012: Vim9: cannot initialize class member with protected var

Problem:  Vim9: cannot initialize class member with protected var
Solution: Allow this to work if this happens within the same class
          (Foxe Chen)

closes: #18949

Signed-off-by: Foxe Chen <chen.foxe@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Foxe Chen
2025-12-23 20:17:30 +00:00
committed by Christian Brabandt
parent 5e577c7aa8
commit cbcc5babba
7 changed files with 35 additions and 2 deletions
+1
View File
@@ -131,6 +131,7 @@ fill_evalarg_from_eap(evalarg_T *evalarg, exarg_T *eap, int skip)
evalarg->eval_getline = eap->ea_getline;
evalarg->eval_cookie = eap->cookie;
}
evalarg->eval_class = eap->class;
}
/*
+2
View File
@@ -1973,6 +1973,8 @@ struct exarg
void *cookie; // argument for getline()
#ifdef FEAT_EVAL
cstack_T *cstack; // condition stack for ":if" etc.
class_T *class; // Name of class being defined. Used by :class
// and :enum commands.
#endif
};
+1 -1
View File
@@ -2025,7 +2025,7 @@ EXTERN listitem_T range_list_item;
EXTERN evalarg_T EVALARG_EVALUATE
# ifdef DO_INIT
= {EVAL_EVALUATE, 0, NULL, NULL, NULL, NULL, GA_EMPTY, GA_EMPTY, NULL,
{0, 0, (int)sizeof(char_u *), 20, NULL}, 0, NULL}
{0, 0, (int)sizeof(char_u *), 20, NULL}, 0, NULL, NULL}
# endif
;
#endif
+3
View File
@@ -2282,6 +2282,9 @@ typedef struct {
// pointer to the lines concatenated for a lambda.
char_u *eval_tofree_lambda;
// pointer to name of class being constructed
class_T *eval_class;
} evalarg_T;
// Flag for expression evaluation.
+22
View File
@@ -12407,10 +12407,14 @@ def Test_protected_new_method()
vim9script
class A
static var _instance: A
static var handler: func = A._Internal
var str: string
def _new(str: string)
this.str = str
enddef
static def _Internal(): string
return "test"
enddef
static def GetInstance(str: string): A
if _instance == null
_instance = A._new(str)
@@ -12422,6 +12426,24 @@ def Test_protected_new_method()
var b: A = A.GetInstance('bar')
assert_equal('foo', a.str)
assert_equal('foo', b.str)
assert_equal('test', A.handler())
END
v9.CheckSourceSuccess(lines)
lines =<< trim END
vim9script
enum Test
A,
B,
C
static var handler: func = Test._Internal
static def _Internal(): string
return "test"
enddef
endenum
assert_equal('test', Test.handler())
END
v9.CheckSourceSuccess(lines)
enddef
+2
View File
@@ -734,6 +734,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
2012,
/**/
2011,
/**/
+4 -1
View File
@@ -2122,6 +2122,8 @@ early_ret:
cl->class_object_type.tt_type = VAR_OBJECT;
cl->class_object_type.tt_class = cl;
eap->class = cl;
// Add the class to the script-local variables.
// TODO: handle other context, e.g. in a function
// TODO: does uf_hash need to be cleared?
@@ -3243,7 +3245,8 @@ class_object_index(
if (fp != NULL)
{
// Protected methods are not accessible outside the class
if (*name == '_')
if (fp->uf_defclass != evalarg->eval_class
&& *name == '_')
{
semsg(_(e_cannot_access_protected_method_str), fp->uf_name);
goto done;